This commit is contained in:
Rajveer86 2023-01-25 01:06:32 +00:00 committed by GitHub
commit 19733e8aa1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 175 additions and 85 deletions

View File

@ -0,0 +1,12 @@
Added the ability to perform keystroke actions on a specific screen only, by adding the flag `activeScreenOnly` to the action (after the screens parameter) e.g.
`keystroke(Control) = keystroke(Super,Mac-Mini,activeScreenOnly)`
This works for both server and clients, with the exception being for keystroke actions intended for the server where the keystroke matches the condition (for instance, adding a custom action on a client, but preserving the original keystroke on the server) e.g.
`keystroke(Control) = keystroke(Super,Mac-Mini,activeScreenOnly), keystroke(Alt,Server,activeScreenOnly)` // This works
`keystroke(Control) = keystroke(Super,Mac-Mini,activeScreenOnly), keystroke(Control,Server,activeScreenOnly)` // This does not work
Since Barrier registers a hotkey for the keystroke condition on the server, this prevents the ability to specify the original keystroke as an action for the server. For this, a new option for the condition allows disabling hotkey registration. This allows the original keystroke to be performed on the primary when it is in focus i.e.
`keystroke(Control,disableGlobalHotkeyRegister) = keystroke(Super,Rajveer-Mac-Mini,activeScreenOnly)` // This allows the original keystroke to perform on the server

View File

@ -43,6 +43,7 @@ IKeyState::KeyInfo::alloc(KeyID id,
info->m_mask = mask; info->m_mask = mask;
info->m_button = button; info->m_button = button;
info->m_count = count; info->m_count = count;
info->m_activeScreenOnly = false;
info->m_screens = NULL; info->m_screens = NULL;
info->m_screensBuffer[0] = '\0'; info->m_screensBuffer[0] = '\0';
return info; return info;
@ -51,7 +52,7 @@ IKeyState::KeyInfo::alloc(KeyID id,
IKeyState::KeyInfo* IKeyState::KeyInfo*
IKeyState::KeyInfo::alloc(KeyID id, IKeyState::KeyInfo::alloc(KeyID id,
KeyModifierMask mask, KeyButton button, SInt32 count, KeyModifierMask mask, KeyButton button, SInt32 count,
const std::set<String>& destinations) const std::set<String>& destinations, bool activeScreenOnly)
{ {
String screens = join(destinations); String screens = join(destinations);
@ -61,6 +62,7 @@ IKeyState::KeyInfo::alloc(KeyID id,
info->m_mask = mask; info->m_mask = mask;
info->m_button = button; info->m_button = button;
info->m_count = count; info->m_count = count;
info->m_activeScreenOnly = activeScreenOnly;
info->m_screens = info->m_screensBuffer; info->m_screens = info->m_screensBuffer;
strcpy(info->m_screensBuffer, screens.c_str()); strcpy(info->m_screensBuffer, screens.c_str());
return info; return info;
@ -75,6 +77,7 @@ IKeyState::KeyInfo::alloc(const KeyInfo& x)
info->m_mask = x.m_mask; info->m_mask = x.m_mask;
info->m_button = x.m_button; info->m_button = x.m_button;
info->m_count = x.m_count; info->m_count = x.m_count;
info->m_activeScreenOnly = x.m_activeScreenOnly;
info->m_screens = x.m_screens ? info->m_screensBuffer : NULL; info->m_screens = x.m_screens ? info->m_screensBuffer : NULL;
strcpy(info->m_screensBuffer, x.m_screensBuffer); strcpy(info->m_screensBuffer, x.m_screensBuffer);
return info; return info;

View File

@ -44,7 +44,7 @@ public:
public: public:
static KeyInfo* alloc(KeyID, KeyModifierMask, KeyButton, SInt32 count); static KeyInfo* alloc(KeyID, KeyModifierMask, KeyButton, SInt32 count);
static KeyInfo* alloc(KeyID, KeyModifierMask, KeyButton, SInt32 count, static KeyInfo* alloc(KeyID, KeyModifierMask, KeyButton, SInt32 count,
const std::set<String>& destinations); const std::set<String>& destinations, bool activeScreenOnly);
static KeyInfo* alloc(const KeyInfo&); static KeyInfo* alloc(const KeyInfo&);
static bool isDefault(const char* screens); static bool isDefault(const char* screens);
@ -58,6 +58,7 @@ public:
KeyModifierMask m_mask; KeyModifierMask m_mask;
KeyButton m_button; KeyButton m_button;
SInt32 m_count; SInt32 m_count;
bool m_activeScreenOnly;
char* m_screens; char* m_screens;
char m_screensBuffer[1]; char m_screensBuffer[1];
}; };

View File

@ -155,8 +155,8 @@ public:
// IPrimaryScreen overrides // IPrimaryScreen overrides
virtual void reconfigure(UInt32 activeSides) = 0; virtual void reconfigure(UInt32 activeSides) = 0;
virtual void warpCursor(SInt32 x, SInt32 y) = 0; virtual void warpCursor(SInt32 x, SInt32 y) = 0;
virtual UInt32 registerHotKey(KeyID key, KeyModifierMask mask) = 0; virtual UInt32 registerHotKey(KeyID key, KeyModifierMask mask, bool registerGlobalHotkey) = 0;
virtual void unregisterHotKey(UInt32 id) = 0; virtual void unregisterHotKey(UInt32 id, bool unregisterGlobalHotkey) = 0;
virtual void fakeInputBegin() = 0; virtual void fakeInputBegin() = 0;
virtual void fakeInputEnd() = 0; virtual void fakeInputEnd() = 0;
virtual SInt32 getJumpZoneSize() const = 0; virtual SInt32 getJumpZoneSize() const = 0;

View File

@ -111,13 +111,13 @@ public:
the modifiers in any order or to require the user to press the given key the modifiers in any order or to require the user to press the given key
last. last.
*/ */
virtual UInt32 registerHotKey(KeyID key, KeyModifierMask mask) = 0; virtual UInt32 registerHotKey(KeyID key, KeyModifierMask mask, bool registerGlobalHotkey) = 0;
//! Unregister a system hotkey //! Unregister a system hotkey
/*! /*!
Unregisters a previously registered hot key. Unregisters a previously registered hot key.
*/ */
virtual void unregisterHotKey(UInt32 id) = 0; virtual void unregisterHotKey(UInt32 id, bool unregisterGlobalHotkey) = 0;
//! Prepare to synthesize input on primary screen //! Prepare to synthesize input on primary screen
/*! /*!

View File

@ -44,8 +44,8 @@ public:
virtual void reconfigure(UInt32 activeSides) = 0; virtual void reconfigure(UInt32 activeSides) = 0;
virtual void warpCursor(SInt32 x, SInt32 y) = 0; virtual void warpCursor(SInt32 x, SInt32 y) = 0;
virtual UInt32 registerHotKey(KeyID key, virtual UInt32 registerHotKey(KeyID key,
KeyModifierMask mask) = 0; KeyModifierMask mask, bool registerGlobalHotkey) = 0;
virtual void unregisterHotKey(UInt32 id) = 0; virtual void unregisterHotKey(UInt32 id, bool unregisterGlobalHotkey) = 0;
virtual void fakeInputBegin() = 0; virtual void fakeInputBegin() = 0;
virtual void fakeInputEnd() = 0; virtual void fakeInputEnd() = 0;
virtual SInt32 getJumpZoneSize() const = 0; virtual SInt32 getJumpZoneSize() const = 0;

View File

@ -330,15 +330,15 @@ Screen::setSequenceNumber(UInt32 seqNum)
} }
UInt32 UInt32
Screen::registerHotKey(KeyID key, KeyModifierMask mask) Screen::registerHotKey(KeyID key, KeyModifierMask mask, bool registerGlobalHotkey)
{ {
return m_screen->registerHotKey(key, mask); return m_screen->registerHotKey(key, mask, registerGlobalHotkey);
} }
void void
Screen::unregisterHotKey(UInt32 id) Screen::unregisterHotKey(UInt32 id, bool unregisterGlobalHotkey)
{ {
m_screen->unregisterHotKey(id); m_screen->unregisterHotKey(id, unregisterGlobalHotkey);
} }
void void

View File

@ -198,13 +198,13 @@ public:
Registers a system-wide hotkey for key \p key with modifiers \p mask. Registers a system-wide hotkey for key \p key with modifiers \p mask.
Returns an id used to unregister the hotkey. Returns an id used to unregister the hotkey.
*/ */
UInt32 registerHotKey(KeyID key, KeyModifierMask mask); UInt32 registerHotKey(KeyID key, KeyModifierMask mask, bool registerGlobalHotkey);
//! Unregister a system hotkey //! Unregister a system hotkey
/*! /*!
Unregisters a previously registered hot key. Unregisters a previously registered hot key.
*/ */
void unregisterHotKey(UInt32 id); void unregisterHotKey(UInt32 id, bool unregisterGlobalHotkey);
//! Prepare to synthesize input on primary screen //! Prepare to synthesize input on primary screen
/*! /*!

View File

@ -548,7 +548,7 @@ void MSWindowsScreen::saveMousePosition(SInt32 x, SInt32 y) {
} }
UInt32 UInt32
MSWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask) MSWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask, bool registerGlobalHotkey)
{ {
// only allow certain modifiers // only allow certain modifiers
if ((mask & ~(KeyModifierShift | KeyModifierControl | if ((mask & ~(KeyModifierShift | KeyModifierControl |
@ -599,12 +599,12 @@ MSWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask)
} }
// if this hot key has modifiers only then we'll handle it specially // if this hot key has modifiers only then we'll handle it specially
bool err; bool err = false;
if (key == kKeyNone) { if (key == kKeyNone) {
// check if already registered // check if already registered
err = (m_hotKeyToIDMap.count(HotKeyItem(vk, modifiers)) > 0); err = (m_hotKeyToIDMap.count(HotKeyItem(vk, modifiers)) > 0);
} }
else { else if (registerGlobalHotkey) {
// register with OS // register with OS
err = (RegisterHotKey(NULL, id, modifiers, vk) == 0); err = (RegisterHotKey(NULL, id, modifiers, vk) == 0);
} }
@ -625,7 +625,7 @@ MSWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask)
} }
void void
MSWindowsScreen::unregisterHotKey(UInt32 id) MSWindowsScreen::unregisterHotKey(UInt32 id, bool unregisterGlobalHotkey)
{ {
// look up hotkey // look up hotkey
HotKeyMap::iterator i = m_hotKeys.find(id); HotKeyMap::iterator i = m_hotKeys.find(id);
@ -634,13 +634,10 @@ MSWindowsScreen::unregisterHotKey(UInt32 id)
} }
// unregister with OS // unregister with OS
bool err; bool err = false;
if (i->second.getVirtualKey() != 0) { if (unregisterGlobalHotkey && i->second.getVirtualKey() != 0) {
err = !UnregisterHotKey(NULL, id); err = !UnregisterHotKey(NULL, id);
} }
else {
err = false;
}
if (err) { if (err) {
LOG((CLOG_WARN "failed to unregister hotkey id=%d", id)); LOG((CLOG_WARN "failed to unregister hotkey id=%d", id));
} }

View File

@ -80,8 +80,8 @@ public:
virtual void reconfigure(UInt32 activeSides); virtual void reconfigure(UInt32 activeSides);
virtual void warpCursor(SInt32 x, SInt32 y); virtual void warpCursor(SInt32 x, SInt32 y);
virtual UInt32 registerHotKey(KeyID key, virtual UInt32 registerHotKey(KeyID key,
KeyModifierMask mask); KeyModifierMask mask, bool registerGlobalHotkey);
virtual void unregisterHotKey(UInt32 id); virtual void unregisterHotKey(UInt32 id, bool unregisterGlobalHotkey);
virtual void fakeInputBegin(); virtual void fakeInputBegin();
virtual void fakeInputEnd(); virtual void fakeInputEnd();
virtual SInt32 getJumpZoneSize() const; virtual SInt32 getJumpZoneSize() const;

View File

@ -68,8 +68,8 @@ public:
// IPrimaryScreen overrides // IPrimaryScreen overrides
virtual void reconfigure(UInt32 activeSides); virtual void reconfigure(UInt32 activeSides);
virtual void warpCursor(SInt32 x, SInt32 y); virtual void warpCursor(SInt32 x, SInt32 y);
virtual UInt32 registerHotKey(KeyID key, KeyModifierMask mask); virtual UInt32 registerHotKey(KeyID key, KeyModifierMask mask, bool registerGlobalHotkey);
virtual void unregisterHotKey(UInt32 id); virtual void unregisterHotKey(UInt32 id, bool unregisterGlobalHotkey);
virtual void fakeInputBegin(); virtual void fakeInputBegin();
virtual void fakeInputEnd(); virtual void fakeInputEnd();
virtual SInt32 getJumpZoneSize() const; virtual SInt32 getJumpZoneSize() const;

View File

@ -315,7 +315,7 @@ OSXScreen::getCursorCenter(SInt32& x, SInt32& y) const
} }
UInt32 UInt32
OSXScreen::registerHotKey(KeyID key, KeyModifierMask mask) OSXScreen::registerHotKey(KeyID key, KeyModifierMask mask, bool registerGlobalHotkey)
{ {
// get mac virtual key and modifier mask matching barrier key and mask // get mac virtual key and modifier mask matching barrier key and mask
UInt32 macKey, macMask; UInt32 macKey, macMask;
@ -336,7 +336,7 @@ OSXScreen::registerHotKey(KeyID key, KeyModifierMask mask)
// if this hot key has modifiers only then we'll handle it specially // if this hot key has modifiers only then we'll handle it specially
EventHotKeyRef ref = NULL; EventHotKeyRef ref = NULL;
bool okay; bool okay = true;
if (key == kKeyNone) { if (key == kKeyNone) {
if (m_modifierHotKeys.count(mask) > 0) { if (m_modifierHotKeys.count(mask) > 0) {
// already registered // already registered
@ -348,11 +348,13 @@ OSXScreen::registerHotKey(KeyID key, KeyModifierMask mask)
} }
} }
else { else {
if (registerGlobalHotkey) {
EventHotKeyID hkid = { 'SNRG', (UInt32)id }; EventHotKeyID hkid = { 'SNRG', (UInt32)id };
OSStatus status = RegisterEventHotKey(macKey, macMask, hkid, OSStatus status = RegisterEventHotKey(macKey, macMask, hkid,
GetApplicationEventTarget(), 0, GetApplicationEventTarget(), 0,
&ref); &ref);
okay = (status == noErr); okay = (status == noErr);
}
m_hotKeyToIDMap[HotKeyItem(macKey, macMask)] = id; m_hotKeyToIDMap[HotKeyItem(macKey, macMask)] = id;
} }
@ -370,7 +372,7 @@ OSXScreen::registerHotKey(KeyID key, KeyModifierMask mask)
} }
void void
OSXScreen::unregisterHotKey(UInt32 id) OSXScreen::unregisterHotKey(UInt32 id, bool unregisterGlobalHotkey)
{ {
// look up hotkey // look up hotkey
HotKeyMap::iterator i = m_hotKeys.find(id); HotKeyMap::iterator i = m_hotKeys.find(id);
@ -379,10 +381,12 @@ OSXScreen::unregisterHotKey(UInt32 id)
} }
// unregister with OS // unregister with OS
bool okay; bool okay = true;
if (i->second.getRef() != NULL) { if (i->second.getRef() != NULL) {
if (unregisterGlobalHotkey) {
okay = (UnregisterEventHotKey(i->second.getRef()) == noErr); okay = (UnregisterEventHotKey(i->second.getRef()) == noErr);
} }
}
else { else {
okay = false; okay = false;
// XXX -- this is inefficient // XXX -- this is inefficient

View File

@ -524,7 +524,7 @@ XWindowsScreen::warpCursor(SInt32 x, SInt32 y)
} }
UInt32 UInt32
XWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask) XWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask, bool registerGlobalHotkey)
{ {
// only allow certain modifiers // only allow certain modifiers
if ((mask & ~(KeyModifierShift | KeyModifierControl | if ((mask & ~(KeyModifierShift | KeyModifierControl |
@ -642,8 +642,10 @@ XWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask)
for (int k = 0; k < modKeymap->max_keypermod && !err; ++k) { for (int k = 0; k < modKeymap->max_keypermod && !err; ++k) {
KeyCode code = modifiermap[k]; KeyCode code = modifiermap[k];
if (modifiermap[k] != 0) { if (modifiermap[k] != 0) {
if (registerGlobalHotkey) {
m_impl->XGrabKey(m_display, code, modifiers2, m_root, m_impl->XGrabKey(m_display, code, modifiers2, m_root,
False, GrabModeAsync, GrabModeAsync); False, GrabModeAsync, GrabModeAsync);
}
if (!err) { if (!err) {
hotKeys.push_back(std::make_pair(code, modifiers2)); hotKeys.push_back(std::make_pair(code, modifiers2));
m_hotKeyToIDMap[HotKeyItem(code, modifiers2)] = id; m_hotKeyToIDMap[HotKeyItem(code, modifiers2)] = id;
@ -689,8 +691,10 @@ XWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask)
} }
// add grab // add grab
if (registerGlobalHotkey) {
m_impl->XGrabKey(m_display, *j, tmpModifiers, m_root, m_impl->XGrabKey(m_display, *j, tmpModifiers, m_root,
False, GrabModeAsync, GrabModeAsync); False, GrabModeAsync, GrabModeAsync);
}
if (!err) { if (!err) {
hotKeys.push_back(std::make_pair(*j, tmpModifiers)); hotKeys.push_back(std::make_pair(*j, tmpModifiers));
m_hotKeyToIDMap[HotKeyItem(*j, tmpModifiers)] = id; m_hotKeyToIDMap[HotKeyItem(*j, tmpModifiers)] = id;
@ -719,7 +723,7 @@ XWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask)
} }
void void
XWindowsScreen::unregisterHotKey(UInt32 id) XWindowsScreen::unregisterHotKey(UInt32 id, bool unregisterGlobalHotkey)
{ {
// look up hotkey // look up hotkey
HotKeyMap::iterator i = m_hotKeys.find(id); HotKeyMap::iterator i = m_hotKeys.find(id);
@ -734,7 +738,9 @@ XWindowsScreen::unregisterHotKey(UInt32 id)
HotKeyList& hotKeys = i->second; HotKeyList& hotKeys = i->second;
for (HotKeyList::iterator j = hotKeys.begin(); for (HotKeyList::iterator j = hotKeys.begin();
j != hotKeys.end(); ++j) { j != hotKeys.end(); ++j) {
if (unregisterGlobalHotkey) {
m_impl->XUngrabKey(m_display, j->first, j->second, m_root); m_impl->XUngrabKey(m_display, j->first, j->second, m_root);
}
m_hotKeyToIDMap.erase(HotKeyItem(j->first, j->second)); m_hotKeyToIDMap.erase(HotKeyItem(j->first, j->second));
} }
} }

View File

@ -53,8 +53,8 @@ public:
// IPrimaryScreen overrides // IPrimaryScreen overrides
virtual void reconfigure(UInt32 activeSides); virtual void reconfigure(UInt32 activeSides);
virtual void warpCursor(SInt32 x, SInt32 y); virtual void warpCursor(SInt32 x, SInt32 y);
virtual UInt32 registerHotKey(KeyID key, KeyModifierMask mask); virtual UInt32 registerHotKey(KeyID key, KeyModifierMask mask, bool registerGlobalHotkey);
virtual void unregisterHotKey(UInt32 id); virtual void unregisterHotKey(UInt32 id, bool unregisterGlobalHotkey);
virtual void fakeInputBegin(); virtual void fakeInputBegin();
virtual void fakeInputEnd(); virtual void fakeInputEnd();
virtual SInt32 getJumpZoneSize() const; virtual SInt32 getJumpZoneSize() const;

View File

@ -1029,13 +1029,19 @@ InputFilter::Condition* Config::parseCondition(ConfigReadContext& s, const std::
const std::vector<std::string>& args) const std::vector<std::string>& args)
{ {
if (name == "keystroke") { if (name == "keystroke") {
if (args.size() != 1) { if (args.size() < 1 || args.size() > 2) {
throw XConfigRead(s, "syntax for condition: keystroke(modifiers+key)"); throw XConfigRead(s, "syntax for condition: keystroke(modifiers+key[,options])");
} }
IPlatformScreen::KeyInfo* keyInfo = s.parseKeystroke(args[0]); IPlatformScreen::KeyInfo* keyInfo = s.parseKeystroke(args[0]);
bool disableGlobalHotkeyRegister = false;
return new InputFilter::KeystrokeCondition(m_events, keyInfo); if (args.size() > 1)
{
parseKeystrokeConditionOptions(s, args[1], disableGlobalHotkeyRegister);
}
return new InputFilter::KeystrokeCondition(m_events, keyInfo, disableGlobalHotkeyRegister);
} }
if (name == "mousebutton") { if (name == "mousebutton") {
@ -1074,8 +1080,8 @@ void Config::parseAction(ConfigReadContext& s, const std::string& name,
InputFilter::Action* action; InputFilter::Action* action;
if (name == "keystroke" || name == "keyDown" || name == "keyUp") { if (name == "keystroke" || name == "keyDown" || name == "keyUp") {
if (args.size() < 1 || args.size() > 2) { if (args.size() < 1 || args.size() > 3) {
throw XConfigRead(s, "syntax for action: keystroke(modifiers+key[,screens])"); throw XConfigRead(s, "syntax for action: keystroke(modifiers+key[,screens[,options]])");
} }
IPlatformScreen::KeyInfo* keyInfo; IPlatformScreen::KeyInfo* keyInfo;
@ -1085,7 +1091,12 @@ void Config::parseAction(ConfigReadContext& s, const std::string& name,
else { else {
std::set<std::string> screens; std::set<std::string> screens;
parseScreens(s, args[1], screens); parseScreens(s, args[1], screens);
keyInfo = s.parseKeystroke(args[0], screens); bool activeScreenOnly = false;
if (args.size() > 2)
{
parseKeystrokeActionOptions(s, args[2], activeScreenOnly);
}
keyInfo = s.parseKeystroke(args[0], screens, activeScreenOnly);
} }
if (name == "keystroke") { if (name == "keystroke") {
@ -1288,6 +1299,32 @@ void Config::parseScreens(ConfigReadContext& c, const std::string& s,
} }
} }
void Config::parseKeystrokeConditionOptions(ConfigReadContext& c, const std::string& s,
bool& disableGlobalHotkeyRegister) const
{
if (s == "disableGlobalHotkeyRegister")
{
disableGlobalHotkeyRegister = true;
}
else
{
disableGlobalHotkeyRegister = false;
}
}
void Config::parseKeystrokeActionOptions(ConfigReadContext& c, const std::string& s,
bool& activeScreenOnly) const
{
if (s == "activeScreenOnly")
{
activeScreenOnly = true;
}
else
{
activeScreenOnly = false;
}
}
const char* const char*
Config::getOptionName(OptionID id) Config::getOptionName(OptionID id)
{ {
@ -2184,6 +2221,13 @@ IPlatformScreen::KeyInfo* ConfigReadContext::parseKeystroke(const std::string& k
IPlatformScreen::KeyInfo* ConfigReadContext::parseKeystroke(const std::string& keystroke, IPlatformScreen::KeyInfo* ConfigReadContext::parseKeystroke(const std::string& keystroke,
const std::set<std::string>& screens) const const std::set<std::string>& screens) const
{
return parseKeystroke(keystroke, screens, false);
}
IPlatformScreen::KeyInfo* ConfigReadContext::parseKeystroke(const std::string& keystroke,
const std::set<std::string>& screens,
const bool& activeScreenOnly) const
{ {
std::string s = keystroke; std::string s = keystroke;
@ -2201,7 +2245,7 @@ IPlatformScreen::KeyInfo* ConfigReadContext::parseKeystroke(const std::string& k
throw XConfigRead(*this, "missing key and/or modifiers in keystroke"); throw XConfigRead(*this, "missing key and/or modifiers in keystroke");
} }
return IPlatformScreen::KeyInfo::alloc(key, mask, 0, 0, screens); return IPlatformScreen::KeyInfo::alloc(key, mask, 0, 0, screens, activeScreenOnly);
} }
IPlatformScreen::ButtonInfo* IPlatformScreen::ButtonInfo*

View File

@ -453,6 +453,9 @@ private:
void parseScreens(ConfigReadContext&, const std::string&, std::set<std::string>& screens) const; void parseScreens(ConfigReadContext&, const std::string&, std::set<std::string>& screens) const;
void parseKeystrokeConditionOptions(ConfigReadContext& c, const std::string& s, bool& activeScreenOnly) const;
void parseKeystrokeActionOptions(ConfigReadContext& c, const std::string& s, bool& activeScreenOnly) const;
static const char* getOptionName(OptionID); static const char* getOptionName(OptionID);
static std::string getOptionValue(OptionID, OptionValue); static std::string getOptionValue(OptionID, OptionValue);
@ -497,6 +500,9 @@ public:
IPlatformScreen::KeyInfo* parseKeystroke(const std::string& keystroke) const; IPlatformScreen::KeyInfo* parseKeystroke(const std::string& keystroke) const;
IPlatformScreen::KeyInfo* parseKeystroke(const std::string& keystroke, IPlatformScreen::KeyInfo* parseKeystroke(const std::string& keystroke,
const std::set<std::string>& screens) const; const std::set<std::string>& screens) const;
IPlatformScreen::KeyInfo* parseKeystroke(const std::string& keystroke,
const std::set<std::string>& screens,
const bool& activeScreenOnly) const;
IPlatformScreen::ButtonInfo* parseMouse(const std::string& mouse) const; IPlatformScreen::ButtonInfo* parseMouse(const std::string& mouse) const;
KeyModifierMask parseModifier(const std::string& modifiers) const; KeyModifierMask parseModifier(const std::string& modifiers) const;

View File

@ -53,21 +53,23 @@ InputFilter::Condition::disablePrimary(PrimaryClient*)
} }
InputFilter::KeystrokeCondition::KeystrokeCondition( InputFilter::KeystrokeCondition::KeystrokeCondition(
IEventQueue* events, IPlatformScreen::KeyInfo* info) : IEventQueue* events, IPlatformScreen::KeyInfo* info, bool disableGlobalHotkeyRegister) :
m_id(0), m_id(0),
m_key(info->m_key), m_key(info->m_key),
m_mask(info->m_mask), m_mask(info->m_mask),
m_events(events) m_events(events),
m_disableGlobalHotkeyRegister(disableGlobalHotkeyRegister)
{ {
free(info); free(info);
} }
InputFilter::KeystrokeCondition::KeystrokeCondition( InputFilter::KeystrokeCondition::KeystrokeCondition(
IEventQueue* events, KeyID key, KeyModifierMask mask) : IEventQueue* events, KeyID key, KeyModifierMask mask, bool disableGlobalHotkeyRegister) :
m_id(0), m_id(0),
m_key(key), m_key(key),
m_mask(mask), m_mask(mask),
m_events(events) m_events(events),
m_disableGlobalHotkeyRegister(disableGlobalHotkeyRegister)
{ {
// do nothing // do nothing
} }
@ -92,7 +94,7 @@ InputFilter::KeystrokeCondition::getMask() const
InputFilter::Condition* InputFilter::Condition*
InputFilter::KeystrokeCondition::clone() const InputFilter::KeystrokeCondition::clone() const
{ {
return new KeystrokeCondition(m_events, m_key, m_mask); return new KeystrokeCondition(m_events, m_key, m_mask, m_disableGlobalHotkeyRegister);
} }
std::string InputFilter::KeystrokeCondition::format() const std::string InputFilter::KeystrokeCondition::format() const
@ -131,13 +133,13 @@ InputFilter::KeystrokeCondition::match(const Event& event)
void void
InputFilter::KeystrokeCondition::enablePrimary(PrimaryClient* primary) InputFilter::KeystrokeCondition::enablePrimary(PrimaryClient* primary)
{ {
m_id = primary->registerHotKey(m_key, m_mask); m_id = primary->registerHotKey(m_key, m_mask, !m_disableGlobalHotkeyRegister);
} }
void void
InputFilter::KeystrokeCondition::disablePrimary(PrimaryClient* primary) InputFilter::KeystrokeCondition::disablePrimary(PrimaryClient* primary)
{ {
primary->unregisterHotKey(m_id); primary->unregisterHotKey(m_id, !m_disableGlobalHotkeyRegister);
m_id = 0; m_id = 0;
} }

View File

@ -57,8 +57,8 @@ public:
// KeystrokeCondition // KeystrokeCondition
class KeystrokeCondition : public Condition { class KeystrokeCondition : public Condition {
public: public:
KeystrokeCondition(IEventQueue* events, IPlatformScreen::KeyInfo*); KeystrokeCondition(IEventQueue* events, IPlatformScreen::KeyInfo*, bool disableGlobalHotkeyRegister);
KeystrokeCondition(IEventQueue* events, KeyID key, KeyModifierMask mask); KeystrokeCondition(IEventQueue* events, KeyID key, KeyModifierMask mask, bool disableGlobalHotkeyRegister);
virtual ~KeystrokeCondition(); virtual ~KeystrokeCondition();
KeyID getKey() const; KeyID getKey() const;
@ -76,6 +76,7 @@ public:
KeyID m_key; KeyID m_key;
KeyModifierMask m_mask; KeyModifierMask m_mask;
IEventQueue* m_events; IEventQueue* m_events;
bool m_disableGlobalHotkeyRegister;
}; };
// MouseButtonCondition // MouseButtonCondition

View File

@ -49,15 +49,15 @@ PrimaryClient::reconfigure(UInt32 activeSides)
} }
UInt32 UInt32
PrimaryClient::registerHotKey(KeyID key, KeyModifierMask mask) PrimaryClient::registerHotKey(KeyID key, KeyModifierMask mask, bool registerGlobalHotkey)
{ {
return m_screen->registerHotKey(key, mask); return m_screen->registerHotKey(key, mask, registerGlobalHotkey);
} }
void void
PrimaryClient::unregisterHotKey(UInt32 id) PrimaryClient::unregisterHotKey(UInt32 id, bool unregisterGlobalHotkey)
{ {
m_screen->unregisterHotKey(id); m_screen->unregisterHotKey(id, unregisterGlobalHotkey);
} }
void void
@ -187,11 +187,7 @@ void
PrimaryClient::keyDown(KeyID key, KeyModifierMask mask, KeyButton button) PrimaryClient::keyDown(KeyID key, KeyModifierMask mask, KeyButton button)
{ {
if (m_fakeInputCount > 0) { if (m_fakeInputCount > 0) {
// XXX -- don't forward keystrokes to primary screen for now m_screen->keyDown(key, mask, button);
(void)key;
(void)mask;
(void)button;
// m_screen->keyDown(key, mask, button);
} }
} }
@ -205,11 +201,7 @@ void
PrimaryClient::keyUp(KeyID key, KeyModifierMask mask, KeyButton button) PrimaryClient::keyUp(KeyID key, KeyModifierMask mask, KeyButton button)
{ {
if (m_fakeInputCount > 0) { if (m_fakeInputCount > 0) {
// XXX -- don't forward keystrokes to primary screen for now m_screen->keyUp(key, mask, button);
(void)key;
(void)mask;
(void)button;
// m_screen->keyUp(key, mask, button);
} }
} }

View File

@ -55,13 +55,13 @@ public:
Registers a system-wide hotkey for key \p key with modifiers \p mask. Registers a system-wide hotkey for key \p key with modifiers \p mask.
Returns an id used to unregister the hotkey. Returns an id used to unregister the hotkey.
*/ */
virtual UInt32 registerHotKey(KeyID key, KeyModifierMask mask); virtual UInt32 registerHotKey(KeyID key, KeyModifierMask mask, bool registerGlobalHotkey);
//! Unregister a system hotkey //! Unregister a system hotkey
/*! /*!
Unregisters a previously registered hot key. Unregisters a previously registered hot key.
*/ */
virtual void unregisterHotKey(UInt32 id); virtual void unregisterHotKey(UInt32 id, bool unregisterGlobalHotkey);
//! Prepare to synthesize input on primary screen //! Prepare to synthesize input on primary screen
/*! /*!

View File

@ -293,7 +293,7 @@ Server::setConfig(const Config& config)
if (!m_config->hasLockToScreenAction()) { if (!m_config->hasLockToScreenAction()) {
IPlatformScreen::KeyInfo* key = IPlatformScreen::KeyInfo* key =
IPlatformScreen::KeyInfo::alloc(kKeyScrollLock, 0, 0, 0); IPlatformScreen::KeyInfo::alloc(kKeyScrollLock, 0, 0, 0);
InputFilter::Rule rule(new InputFilter::KeystrokeCondition(m_events, key)); InputFilter::Rule rule(new InputFilter::KeystrokeCondition(m_events, key, true));
rule.adoptAction(new InputFilter::LockCursorToScreenAction(m_events), true); rule.adoptAction(new InputFilter::LockCursorToScreenAction(m_events), true);
m_inputFilter->addFilterRule(rule); m_inputFilter->addFilterRule(rule);
} }
@ -1285,7 +1285,9 @@ Server::handleKeyDownEvent(const Event& event, void*)
{ {
IPlatformScreen::KeyInfo* info = IPlatformScreen::KeyInfo* info =
static_cast<IPlatformScreen::KeyInfo*>(event.getData()); static_cast<IPlatformScreen::KeyInfo*>(event.getData());
onKeyDown(info->m_key, info->m_mask, info->m_button, info->m_screens); onKeyDown(info->m_key, info->m_mask, info->m_button,
info->m_screens,
info->m_activeScreenOnly);
} }
void void
@ -1293,7 +1295,9 @@ Server::handleKeyUpEvent(const Event& event, void*)
{ {
IPlatformScreen::KeyInfo* info = IPlatformScreen::KeyInfo* info =
static_cast<IPlatformScreen::KeyInfo*>(event.getData()); static_cast<IPlatformScreen::KeyInfo*>(event.getData());
onKeyUp(info->m_key, info->m_mask, info->m_button, info->m_screens); onKeyUp(info->m_key, info->m_mask, info->m_button,
info->m_screens,
info->m_activeScreenOnly);
} }
void void
@ -1630,7 +1634,7 @@ Server::onScreensaver(bool activated)
void void
Server::onKeyDown(KeyID id, KeyModifierMask mask, KeyButton button, Server::onKeyDown(KeyID id, KeyModifierMask mask, KeyButton button,
const char* screens) const char* screens, bool activeScreenOnly)
{ {
LOG((CLOG_DEBUG1 "onKeyDown id=%d mask=0x%04x button=0x%04x", id, mask, button)); LOG((CLOG_DEBUG1 "onKeyDown id=%d mask=0x%04x button=0x%04x", id, mask, button));
assert(m_active != NULL); assert(m_active != NULL);
@ -1639,6 +1643,15 @@ Server::onKeyDown(KeyID id, KeyModifierMask mask, KeyButton button,
if (!m_keyboardBroadcasting && IKeyState::KeyInfo::isDefault(screens)) { if (!m_keyboardBroadcasting && IKeyState::KeyInfo::isDefault(screens)) {
m_active->keyDown(id, mask, button); m_active->keyDown(id, mask, button);
} }
else if (activeScreenOnly) {
auto activeName = m_active->getName();
if (IKeyState::KeyInfo::contains(screens, activeName)) {
// This won't work on the primary client if the action has the same keystroke as the condition.
// Unlike other clients, the primary client registers the original keystroke with the OS as a hotkey to block
// other apps from handling them, which also stops Barrier from being able to create a fake event for them.
m_active->keyDown(id, mask, button);
}
}
else { else {
if (!screens && m_keyboardBroadcasting) { if (!screens && m_keyboardBroadcasting) {
screens = m_keyboardBroadcastingScreens.c_str(); screens = m_keyboardBroadcastingScreens.c_str();
@ -1657,7 +1670,7 @@ Server::onKeyDown(KeyID id, KeyModifierMask mask, KeyButton button,
void void
Server::onKeyUp(KeyID id, KeyModifierMask mask, KeyButton button, Server::onKeyUp(KeyID id, KeyModifierMask mask, KeyButton button,
const char* screens) const char* screens, bool activeScreenOnly)
{ {
LOG((CLOG_DEBUG1 "onKeyUp id=%d mask=0x%04x button=0x%04x", id, mask, button)); LOG((CLOG_DEBUG1 "onKeyUp id=%d mask=0x%04x button=0x%04x", id, mask, button));
assert(m_active != NULL); assert(m_active != NULL);
@ -1666,6 +1679,15 @@ Server::onKeyUp(KeyID id, KeyModifierMask mask, KeyButton button,
if (!m_keyboardBroadcasting && IKeyState::KeyInfo::isDefault(screens)) { if (!m_keyboardBroadcasting && IKeyState::KeyInfo::isDefault(screens)) {
m_active->keyUp(id, mask, button); m_active->keyUp(id, mask, button);
} }
else if (activeScreenOnly) {
auto activeName = m_active->getName();
if (IKeyState::KeyInfo::contains(screens, activeName)) {
// This won't work on the primary client if the action has the same keystroke as the condition.
// Unlike other clients, the primary client registers the original keystroke with the OS as a hotkey to block
// other apps from handling them, which also stops Barrier from being able to create a fake event for them.
m_active->keyUp(id, mask, button);
}
}
else { else {
if (!screens && m_keyboardBroadcasting) { if (!screens && m_keyboardBroadcasting) {
screens = m_keyboardBroadcastingScreens.c_str(); screens = m_keyboardBroadcastingScreens.c_str();

View File

@ -322,9 +322,9 @@ private:
ClipboardID id, UInt32 seqNum); ClipboardID id, UInt32 seqNum);
void onScreensaver(bool activated); void onScreensaver(bool activated);
void onKeyDown(KeyID, KeyModifierMask, KeyButton, void onKeyDown(KeyID, KeyModifierMask, KeyButton,
const char* screens); const char* screens, bool activeScreenOnly);
void onKeyUp(KeyID, KeyModifierMask, KeyButton, void onKeyUp(KeyID, KeyModifierMask, KeyButton,
const char* screens); const char* screens, bool activeScreenOnly);
void onKeyRepeat(KeyID, KeyModifierMask, SInt32, KeyButton); void onKeyRepeat(KeyID, KeyModifierMask, SInt32, KeyButton);
void onMouseDown(ButtonID); void onMouseDown(ButtonID);
void onMouseUp(ButtonID); void onMouseUp(ButtonID);