[FEATURE] Add ability to perform keystrokes on only the active screen, if thatactive screen exists in `screens`

This commit is contained in:
Rajveer Aujla 2023-01-19 13:32:33 +00:00
parent 653e4badeb
commit f38ab7d569
7 changed files with 70 additions and 22 deletions

View File

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

View File

@ -44,7 +44,7 @@ public:
public:
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 bool isDefault(const char* screens);
@ -58,6 +58,7 @@ public:
KeyModifierMask m_mask;
KeyButton m_button;
SInt32 m_count;
bool m_activeScreenOnly;
char* m_screens;
char m_screensBuffer[1];
};

View File

@ -1074,8 +1074,8 @@ void Config::parseAction(ConfigReadContext& s, const std::string& name,
InputFilter::Action* action;
if (name == "keystroke" || name == "keyDown" || name == "keyUp") {
if (args.size() < 1 || args.size() > 2) {
throw XConfigRead(s, "syntax for action: keystroke(modifiers+key[,screens])");
if (args.size() < 1 || args.size() > 3) {
throw XConfigRead(s, "syntax for action: keystroke(modifiers+key[,screens[,options]])");
}
IPlatformScreen::KeyInfo* keyInfo;
@ -1085,7 +1085,12 @@ void Config::parseAction(ConfigReadContext& s, const std::string& name,
else {
std::set<std::string> 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") {
@ -1288,6 +1293,19 @@ void Config::parseScreens(ConfigReadContext& c, const std::string& s,
}
}
void Config::parseKeystrokeActionOptions(ConfigReadContext& c, const std::string& s,
bool& activeScreenOnly) const
{
if (s == "activeScreenOnly")
{
activeScreenOnly = true;
}
else
{
activeScreenOnly = false;
}
}
const char*
Config::getOptionName(OptionID id)
{
@ -2184,6 +2202,13 @@ IPlatformScreen::KeyInfo* ConfigReadContext::parseKeystroke(const std::string& k
IPlatformScreen::KeyInfo* ConfigReadContext::parseKeystroke(const std::string& keystroke,
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;
@ -2201,7 +2226,7 @@ IPlatformScreen::KeyInfo* ConfigReadContext::parseKeystroke(const std::string& k
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*

View File

@ -453,6 +453,8 @@ private:
void parseScreens(ConfigReadContext&, const std::string&, std::set<std::string>& screens) const;
void parseKeystrokeActionOptions(ConfigReadContext& c, const std::string& s, bool& activeScreenOnly) const;
static const char* getOptionName(OptionID);
static std::string getOptionValue(OptionID, OptionValue);
@ -497,6 +499,9 @@ public:
IPlatformScreen::KeyInfo* parseKeystroke(const std::string& keystroke) const;
IPlatformScreen::KeyInfo* parseKeystroke(const std::string& keystroke,
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;
KeyModifierMask parseModifier(const std::string& modifiers) const;

View File

@ -187,11 +187,7 @@ void
PrimaryClient::keyDown(KeyID key, KeyModifierMask mask, KeyButton button)
{
if (m_fakeInputCount > 0) {
// XXX -- don't forward keystrokes to primary screen for now
(void)key;
(void)mask;
(void)button;
// m_screen->keyDown(key, mask, button);
m_screen->keyDown(key, mask, button);
}
}
@ -205,11 +201,7 @@ void
PrimaryClient::keyUp(KeyID key, KeyModifierMask mask, KeyButton button)
{
if (m_fakeInputCount > 0) {
// XXX -- don't forward keystrokes to primary screen for now
(void)key;
(void)mask;
(void)button;
// m_screen->keyUp(key, mask, button);
m_screen->keyUp(key, mask, button);
}
}

View File

@ -1285,7 +1285,9 @@ Server::handleKeyDownEvent(const Event& event, void*)
{
IPlatformScreen::KeyInfo* info =
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
@ -1293,7 +1295,9 @@ Server::handleKeyUpEvent(const Event& event, void*)
{
IPlatformScreen::KeyInfo* info =
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
@ -1630,7 +1634,7 @@ Server::onScreensaver(bool activated)
void
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));
assert(m_active != NULL);
@ -1639,6 +1643,15 @@ Server::onKeyDown(KeyID id, KeyModifierMask mask, KeyButton button,
if (!m_keyboardBroadcasting && IKeyState::KeyInfo::isDefault(screens)) {
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 {
if (!screens && m_keyboardBroadcasting) {
screens = m_keyboardBroadcastingScreens.c_str();
@ -1657,7 +1670,7 @@ Server::onKeyDown(KeyID id, KeyModifierMask mask, KeyButton button,
void
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));
assert(m_active != NULL);
@ -1666,6 +1679,15 @@ Server::onKeyUp(KeyID id, KeyModifierMask mask, KeyButton button,
if (!m_keyboardBroadcasting && IKeyState::KeyInfo::isDefault(screens)) {
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 {
if (!screens && m_keyboardBroadcasting) {
screens = m_keyboardBroadcastingScreens.c_str();

View File

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