Actually, it's quite a bit of work to get super key binding support working. Let's hold off on that...
parent
7a5c11fd81
commit
70efe54f8e
@ -1,241 +0,0 @@
|
||||
Description: Add super key binding support.
|
||||
This commit contains three patches that was done in one upstream pull request
|
||||
but the commits weren't squashed. The commit descriptions are as follows:
|
||||
- Free the storage returned by XGetKeyboardMapping.
|
||||
- Daemon triggers on KeyRelease.
|
||||
- Register meta keys for shortcuts.
|
||||
- Triggering shortcuts with meta keys.
|
||||
Author: ska67 <git17@ska67.de>
|
||||
Origin: backport
|
||||
Bug: https://github.com/lxde/lxqt/issues/1259
|
||||
Applied-Upstream: commit
|
||||
Last-Update: 2018-02-05
|
||||
--- a/daemon/core.cpp
|
||||
+++ b/daemon/core.cpp
|
||||
@@ -1120,7 +1120,7 @@ void Core::run()
|
||||
|
||||
Window rootWindow = DefaultRootWindow(mDisplay);
|
||||
|
||||
- XSelectInput(mDisplay, rootWindow, KeyPressMask);
|
||||
+ XSelectInput(mDisplay, rootWindow, KeyPressMask | KeyReleaseMask);
|
||||
|
||||
mInterClientCommunicationWindow = XCreateSimpleWindow(mDisplay, rootWindow, 0, 0, 1, 1, 0, 0, 0);
|
||||
|
||||
@@ -1140,10 +1140,14 @@ void Core::run()
|
||||
allModifiers.insert(ignoreLocks);
|
||||
}
|
||||
|
||||
+ const QString metaLeft = XKeysymToString(XK_Super_L);
|
||||
+ const QString metaRight = XKeysymToString(XK_Super_R);
|
||||
|
||||
char signal = 0;
|
||||
if (write(mX11ResponsePipe[STDOUT_FILENO], &signal, sizeof(signal)) == sizeof(signal))
|
||||
{
|
||||
+ bool keyReleaseExpected = false;
|
||||
+
|
||||
XEvent event;
|
||||
while (mX11EventLoopActive)
|
||||
{
|
||||
@@ -1153,7 +1157,15 @@ void Core::run()
|
||||
break;
|
||||
}
|
||||
|
||||
- if (event.type == KeyPress && mDataMutex.tryLock(0))
|
||||
+ if ((event.type == KeyRelease) && !keyReleaseExpected)
|
||||
+ {
|
||||
+ // pop event from the x11 queue and do nothing
|
||||
+ XNextEvent(mDisplay, &event);
|
||||
+ continue;
|
||||
+ }
|
||||
+ keyReleaseExpected = false; // Close time window for accepting meta keys.
|
||||
+
|
||||
+ if (((event.type == KeyPress) || (event.type == KeyRelease)) && mDataMutex.tryLock(0))
|
||||
{
|
||||
std::unique_lock<QMutex> unlocker(mDataMutex, std::adopt_lock);
|
||||
|
||||
@@ -1201,7 +1213,29 @@ void Core::run()
|
||||
}
|
||||
else
|
||||
{
|
||||
- if (isModifier(keySym) || !isAllowed(keySym, event.xkey.state & allShifts))
|
||||
+ if (isModifier(keySym))
|
||||
+ {
|
||||
+ if (event.type == KeyPress)
|
||||
+ {
|
||||
+ ignoreKey = true;
|
||||
+ keyReleaseExpected = true;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ // Only the meta keys are allowed.
|
||||
+
|
||||
+ if ((event.xkey.state & allShifts) == MetaMask)
|
||||
+ {
|
||||
+ shortcut = XKeysymToString(keySym);
|
||||
+ event.xkey.state &= ~allShifts; // Modifier keys must not use shift states.
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ignoreKey = true;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ else if ((event.type == KeyRelease) || !isAllowed(keySym, event.xkey.state & allShifts))
|
||||
{
|
||||
ignoreKey = true;
|
||||
}
|
||||
@@ -1243,6 +1277,11 @@ void Core::run()
|
||||
}
|
||||
}
|
||||
}
|
||||
+ if (keySyms)
|
||||
+ {
|
||||
+ XFree(keySyms);
|
||||
+ keySyms = nullptr;
|
||||
+ }
|
||||
if (!ignoreKey)
|
||||
{
|
||||
IdsByShortcut::iterator idsByShortcut = mIdsByShortcut.find(shortcut);
|
||||
@@ -1316,65 +1355,84 @@ void Core::run()
|
||||
}
|
||||
else
|
||||
{
|
||||
+ if (event.type == KeyRelease)
|
||||
+ {
|
||||
+ event.xkey.state &= ~allShifts; // Modifier keys must not use shift states.
|
||||
+ }
|
||||
+
|
||||
X11Shortcut shortcutKey = qMakePair(static_cast<KeyCode>(event.xkey.keycode), event.xkey.state & allShifts);
|
||||
ShortcutByX11::const_iterator shortcutIt = mShortcutByX11.constFind(shortcutKey);
|
||||
- if(shortcutIt != mShortcutByX11.constEnd())
|
||||
+ if (shortcutIt == mShortcutByX11.constEnd())
|
||||
{
|
||||
- const QString& shortcut = shortcutIt.value();
|
||||
- log(LOG_DEBUG, "KeyPress %08x %08x %s", event.xkey.state & allShifts, event.xkey.keycode, qPrintable(shortcut));
|
||||
+ continue;
|
||||
+ }
|
||||
+ const QString& shortcut = shortcutIt.value();
|
||||
|
||||
- IdsByShortcut::iterator idsByShortcut = mIdsByShortcut.find(shortcut);
|
||||
- if (idsByShortcut != mIdsByShortcut.end())
|
||||
+ if (event.type == KeyPress)
|
||||
+ {
|
||||
+ if ((shortcut == metaLeft) || (shortcut == metaRight))
|
||||
{
|
||||
- Ids &ids = idsByShortcut.value();
|
||||
- switch (mMultipleActionsBehaviour)
|
||||
- {
|
||||
- case MULTIPLE_ACTIONS_BEHAVIOUR_FIRST:
|
||||
- {
|
||||
- Ids::iterator lastIds = ids.end();
|
||||
- for (Ids::iterator idi = ids.begin(); idi != lastIds; ++idi)
|
||||
- if (mShortcutAndActionById[*idi].second->call())
|
||||
- {
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- break;
|
||||
+ keyReleaseExpected = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+ log(LOG_DEBUG, "KeyPress %08x %08x %s", event.xkey.state & allShifts, event.xkey.keycode, qPrintable(shortcut));
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ log(LOG_DEBUG, "KeyRelease %08x %08x %s", event.xkey.state & allShifts, event.xkey.keycode, qPrintable(shortcut));
|
||||
+ }
|
||||
|
||||
- case MULTIPLE_ACTIONS_BEHAVIOUR_LAST:
|
||||
- {
|
||||
- Ids::iterator firstIds = ids.begin();
|
||||
- for (Ids::iterator idi = ids.end(); idi != firstIds;)
|
||||
+ IdsByShortcut::iterator idsByShortcut = mIdsByShortcut.find(shortcut);
|
||||
+ if (idsByShortcut != mIdsByShortcut.end())
|
||||
+ {
|
||||
+ Ids &ids = idsByShortcut.value();
|
||||
+ switch (mMultipleActionsBehaviour)
|
||||
+ {
|
||||
+ case MULTIPLE_ACTIONS_BEHAVIOUR_FIRST:
|
||||
+ {
|
||||
+ Ids::iterator lastIds = ids.end();
|
||||
+ for (Ids::iterator idi = ids.begin(); idi != lastIds; ++idi)
|
||||
+ if (mShortcutAndActionById[*idi].second->call())
|
||||
{
|
||||
- --idi;
|
||||
- if (mShortcutAndActionById[*idi].second->call())
|
||||
- {
|
||||
- break;
|
||||
- }
|
||||
+ break;
|
||||
}
|
||||
- }
|
||||
- break;
|
||||
+ }
|
||||
+ break;
|
||||
|
||||
- case MULTIPLE_ACTIONS_BEHAVIOUR_NONE:
|
||||
- if (ids.size() == 1)
|
||||
+ case MULTIPLE_ACTIONS_BEHAVIOUR_LAST:
|
||||
+ {
|
||||
+ Ids::iterator firstIds = ids.begin();
|
||||
+ for (Ids::iterator idi = ids.end(); idi != firstIds;)
|
||||
+ {
|
||||
+ --idi;
|
||||
+ if (mShortcutAndActionById[*idi].second->call())
|
||||
{
|
||||
- mShortcutAndActionById[*(ids.begin())].second->call();
|
||||
+ break;
|
||||
}
|
||||
- break;
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
|
||||
- case MULTIPLE_ACTIONS_BEHAVIOUR_ALL:
|
||||
+ case MULTIPLE_ACTIONS_BEHAVIOUR_NONE:
|
||||
+ if (ids.size() == 1)
|
||||
{
|
||||
- Ids::iterator lastIds = ids.end();
|
||||
- for (Ids::iterator idi = ids.begin(); idi != lastIds; ++idi)
|
||||
- {
|
||||
- mShortcutAndActionById[*idi].second->call();
|
||||
- }
|
||||
+ mShortcutAndActionById[*(ids.begin())].second->call();
|
||||
}
|
||||
break;
|
||||
|
||||
- default:
|
||||
- ;
|
||||
+ case MULTIPLE_ACTIONS_BEHAVIOUR_ALL:
|
||||
+ {
|
||||
+ Ids::iterator lastIds = ids.end();
|
||||
+ for (Ids::iterator idi = ids.begin(); idi != lastIds; ++idi)
|
||||
+ {
|
||||
+ mShortcutAndActionById[*idi].second->call();
|
||||
}
|
||||
}
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ ;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1382,7 +1440,7 @@ void Core::run()
|
||||
else
|
||||
// check for pending pipe requests from other thread
|
||||
{
|
||||
- if (event.type != KeyPress) {
|
||||
+ if ((event.type != KeyPress) && (event.type != KeyRelease)) {
|
||||
XNextEvent(mDisplay, &event);
|
||||
}
|
||||
|
||||
@@ -2631,6 +2689,7 @@ void Core::changeClientActionShortcut(QP
|
||||
result = qMakePair(QString(), id);
|
||||
return;
|
||||
}
|
||||
+ keyReleaseExpected = false; // Close time window for accepting meta keys.
|
||||
|
||||
IdsByShortcut::iterator idsByShortcut = mIdsByShortcut.find(oldShortcut);
|
||||
if (idsByShortcut != mIdsByShortcut.end())
|
Loading…
Reference in new issue