aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--minetest.conf.example4
-rw-r--r--src/client/keycode.cpp9
-rw-r--r--src/client/keycode.h3
-rw-r--r--src/defaultsettings.cpp1
-rw-r--r--src/gui/guiChatConsole.cpp67
-rw-r--r--src/gui/guiChatConsole.h6
6 files changed, 87 insertions, 3 deletions
diff --git a/minetest.conf.example b/minetest.conf.example
index 814e34e43..524ef6334 100644
--- a/minetest.conf.example
+++ b/minetest.conf.example
@@ -24,6 +24,10 @@
# type: string
# chat_weblink_color = 8888FF
+# If clickable_chat_weblinks is enabled, specify the keys held down to treat left-click as middle-click.
+# type: string (comma-delimited)
+# chat_weblink_ctrl_keys = KEY_LCONTROL,KEY_RCONTROL,KEY_CONTROL
+
# If enabled, you can place blocks at the position (feet + eye level) where you stand.
# This is helpful when working with nodeboxes in small areas.
# type: bool
diff --git a/src/client/keycode.cpp b/src/client/keycode.cpp
index ce5214f54..08aff43ce 100644
--- a/src/client/keycode.cpp
+++ b/src/client/keycode.cpp
@@ -386,3 +386,12 @@ irr::EKEY_CODE keyname_to_keycode(const char *name)
{
return lookup_keyname(name).Key;
}
+
+irr::EKEY_CODE keyname_to_keycode_safemode(const char *name)
+{
+ try {
+ return lookup_keyname(name).Key;
+ } catch (UnknownKeycode &e) {
+ return irr::KEY_KEY_CODES_COUNT;
+ }
+}
diff --git a/src/client/keycode.h b/src/client/keycode.h
index 7036705d1..cb3114099 100644
--- a/src/client/keycode.h
+++ b/src/client/keycode.h
@@ -65,3 +65,6 @@ KeyPress getKeySetting(const char *settingname);
void clearKeyCache();
irr::EKEY_CODE keyname_to_keycode(const char *name);
+
+// Now with internal exception handling. return irr::KEY_KEY_CODES_COUNT on fail
+irr::EKEY_CODE keyname_to_keycode_safemode(const char *name);
diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp
index c59b93e88..132e31d2b 100644
--- a/src/defaultsettings.cpp
+++ b/src/defaultsettings.cpp
@@ -284,6 +284,7 @@ void set_default_settings()
settings->setDefault("joystick_deadzone", "2048");
settings->setDefault("clickable_chat_weblinks", "false");
settings->setDefault("chat_weblink_color", "8888FF");
+ settings->setDefault("chat_weblink_ctrl_keys", "KEY_LCONTROL,KEY_RCONTROL,KEY_CONTROL");
// Main menu
settings->setDefault("main_menu_path", "");
diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp
index f5336e3ad..08d26efc2 100644
--- a/src/gui/guiChatConsole.cpp
+++ b/src/gui/guiChatConsole.cpp
@@ -90,8 +90,19 @@ GUIChatConsole::GUIChatConsole(
// set default cursor options
setCursor(true, true, 2.0, 0.1);
-
+
m_cache_clickable_chat_weblinks = g_settings->getBool("clickable_chat_weblinks");
+ if(m_cache_clickable_chat_weblinks)
+ {
+ std::string ctrlkeystoparse = g_settings->get("chat_weblink_ctrl_keys");
+ if(setupChatClickCtrlKeys(ctrlkeystoparse) == 0)
+ {
+ // if fail then try again w hardcoded string
+ g_logger.log(LL_WARNING, "Failed to parse chat_weblink_ctrl_keys. Using hardcoded default.");
+ ctrlkeystoparse = "KEY_CONTROL,KEY_LCONTROL,KEY_RCONTROL";
+ setupChatClickCtrlKeys(ctrlkeystoparse);
+ }
+ }
}
GUIChatConsole::~GUIChatConsole()
@@ -412,7 +423,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
if(event.EventType == EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
{
// CTRL up
- if(event.KeyInput.Key == KEY_LCONTROL || event.KeyInput.Key == KEY_RCONTROL || !event.KeyInput.Control)
+ if(isInCtrlKeys(event.KeyInput.Key) || !event.KeyInput.Control)
{
isctrldown = false;
}
@@ -420,7 +431,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
else if(event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown)
{
// CTRL down
- if(event.KeyInput.Key == KEY_LCONTROL || event.KeyInput.Key == KEY_RCONTROL || event.KeyInput.Control)
+ if(isInCtrlKeys(event.KeyInput.Key) || event.KeyInput.Control)
{
isctrldown = true;
}
@@ -669,3 +680,53 @@ void GUIChatConsole::setVisible(bool visible)
}
}
+// Return how many "ctrl" keycodes successfully found in string, or 0 on fail
+int GUIChatConsole::setupChatClickCtrlKeys(std::string inputline)
+{
+ m_cache_chat_weblink_ctrl_keys.clear();
+
+ irr::EKEY_CODE kc;
+ std::string stemp;
+ size_t startpos = 0, endpos = 0;
+ while(startpos < inputline.size())
+ {
+ // Foreach delimited string,
+ endpos = inputline.find(',', startpos);
+ endpos = std::min(endpos, inputline.find(' ', startpos));
+ // Ignore space/comma
+ if(endpos == startpos)
+ {
+ ++endpos;
+ }
+ // Ignore consecutive space/comma
+ else if(endpos - startpos > 1)
+ {
+ // If valid keycode, add it to cached list
+ stemp = inputline.substr(startpos, endpos - startpos);
+ kc = keyname_to_keycode_safemode(stemp.c_str());
+ if(kc != irr::KEY_KEY_CODES_COUNT)
+ {
+ m_cache_chat_weblink_ctrl_keys.push_back(kc);
+ }
+ else
+ {
+ stemp = "Ignoring unknown keycode '" + stemp + "' for chat_weblink_ctrl_keys, check your conf";
+ g_logger.log(LL_WARNING, stemp);
+ }
+ }
+ startpos = endpos;
+ }
+
+ return m_cache_chat_weblink_ctrl_keys.size();
+}
+
+bool GUIChatConsole::isInCtrlKeys(const irr::EKEY_CODE& kc)
+{
+ // To avoid including <algorithm>
+ for(size_t i=0; i<m_cache_chat_weblink_ctrl_keys.size(); ++i)
+ {
+ if(m_cache_chat_weblink_ctrl_keys.at(i) == kc)
+ return true;
+ }
+ return false;
+}
diff --git a/src/gui/guiChatConsole.h b/src/gui/guiChatConsole.h
index 501bf50cb..058b78f28 100644
--- a/src/gui/guiChatConsole.h
+++ b/src/gui/guiChatConsole.h
@@ -82,6 +82,10 @@ private:
void drawText();
void drawPrompt();
+ // Parse conf and populate "ctrl" keys for clickable chat
+ int setupChatClickCtrlKeys(std::string inputline);
+ bool isInCtrlKeys(const irr::EKEY_CODE& kc);
+
private:
ChatBackend* m_chat_backend;
Client* m_client;
@@ -127,4 +131,6 @@ private:
// Enable clickable chat weblinks
bool m_cache_clickable_chat_weblinks;
+ // Set of "control" keys for weblink mouseclicks
+ std::vector<irr::EKEY_CODE> m_cache_chat_weblink_ctrl_keys;
};