headless: userscript bind hotkey
This commit is contained in:
parent
5e77cb4577
commit
7709db832b
|
@ -26,7 +26,8 @@ const char* Action::m_ActionTypeNames[] =
|
||||||
"keyDown", "keyUp", "keystroke",
|
"keyDown", "keyUp", "keystroke",
|
||||||
"switchToScreen", "toggleScreen",
|
"switchToScreen", "toggleScreen",
|
||||||
"switchInDirection", "lockCursorToScreen",
|
"switchInDirection", "lockCursorToScreen",
|
||||||
"mouseDown", "mouseUp", "mousebutton"
|
"userScript",
|
||||||
|
"mouseDown", "mouseUp", "mousebutton",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* Action::m_SwitchDirectionNames[] = { "left", "right", "up", "down" };
|
const char* Action::m_SwitchDirectionNames[] = { "left", "right", "up", "down" };
|
||||||
|
@ -37,6 +38,7 @@ Action::Action() :
|
||||||
m_Type(keystroke),
|
m_Type(keystroke),
|
||||||
m_TypeScreenNames(),
|
m_TypeScreenNames(),
|
||||||
m_SwitchScreenName(),
|
m_SwitchScreenName(),
|
||||||
|
m_UserScriptCommand(),
|
||||||
m_SwitchDirection(switchLeft),
|
m_SwitchDirection(switchLeft),
|
||||||
m_LockCursorMode(lockCursorToggle),
|
m_LockCursorMode(lockCursorToggle),
|
||||||
m_ActiveOnRelease(false),
|
m_ActiveOnRelease(false),
|
||||||
|
@ -105,6 +107,11 @@ QString Action::text() const
|
||||||
text += ")";
|
text += ")";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case userScript:
|
||||||
|
text += "(";
|
||||||
|
text += userScriptCommand();
|
||||||
|
text += ")";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Q_ASSERT(0);
|
Q_ASSERT(0);
|
||||||
break;
|
break;
|
||||||
|
@ -133,6 +140,7 @@ void Action::loadSettings(QSettings& settings)
|
||||||
setLockCursorMode(settings.value("lockCursorToScreen", lockCursorToggle).toInt());
|
setLockCursorMode(settings.value("lockCursorToScreen", lockCursorToggle).toInt());
|
||||||
setActiveOnRelease(settings.value("activeOnRelease", false).toBool());
|
setActiveOnRelease(settings.value("activeOnRelease", false).toBool());
|
||||||
setHaveScreens(settings.value("hasScreens", false).toBool());
|
setHaveScreens(settings.value("hasScreens", false).toBool());
|
||||||
|
setUserScriptCommand(settings.value("userScriptCommand").toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Action::saveSettings(QSettings& settings) const
|
void Action::saveSettings(QSettings& settings) const
|
||||||
|
@ -153,6 +161,7 @@ void Action::saveSettings(QSettings& settings) const
|
||||||
settings.setValue("lockCursorToScreen", lockCursorMode());
|
settings.setValue("lockCursorToScreen", lockCursorMode());
|
||||||
settings.setValue("activeOnRelease", activeOnRelease());
|
settings.setValue("activeOnRelease", activeOnRelease());
|
||||||
settings.setValue("hasScreens", haveScreens());
|
settings.setValue("hasScreens", haveScreens());
|
||||||
|
settings.setValue("userScriptCommand", userScriptCommand());
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextStream& operator<<(QTextStream& outStream, const Action& action)
|
QTextStream& operator<<(QTextStream& outStream, const Action& action)
|
||||||
|
|
|
@ -35,7 +35,8 @@ class Action
|
||||||
public:
|
public:
|
||||||
enum ActionType { keyDown, keyUp, keystroke,
|
enum ActionType { keyDown, keyUp, keystroke,
|
||||||
switchToScreen, toggleScreen, switchInDirection,
|
switchToScreen, toggleScreen, switchInDirection,
|
||||||
lockCursorToScreen, mouseDown, mouseUp, mousebutton };
|
lockCursorToScreen, userScript,
|
||||||
|
mouseDown, mouseUp, mousebutton };
|
||||||
enum SwitchDirection { switchLeft, switchRight, switchUp, switchDown };
|
enum SwitchDirection { switchLeft, switchRight, switchUp, switchDown };
|
||||||
enum LockCursorMode { lockCursorToggle, lockCursonOn, lockCursorOff };
|
enum LockCursorMode { lockCursorToggle, lockCursonOn, lockCursorOff };
|
||||||
|
|
||||||
|
@ -72,11 +73,15 @@ class Action
|
||||||
bool haveScreens() const { return m_HasScreens; }
|
bool haveScreens() const { return m_HasScreens; }
|
||||||
void setHaveScreens(bool b) { m_HasScreens = b; }
|
void setHaveScreens(bool b) { m_HasScreens = b; }
|
||||||
|
|
||||||
|
const QString& userScriptCommand() const { return m_UserScriptCommand; }
|
||||||
|
void setUserScriptCommand(const QString& n) { m_UserScriptCommand = n; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KeySequence m_KeySequence;
|
KeySequence m_KeySequence;
|
||||||
int m_Type;
|
int m_Type;
|
||||||
QStringList m_TypeScreenNames;
|
QStringList m_TypeScreenNames;
|
||||||
QString m_SwitchScreenName;
|
QString m_SwitchScreenName;
|
||||||
|
QString m_UserScriptCommand;
|
||||||
int m_SwitchDirection;
|
int m_SwitchDirection;
|
||||||
int m_LockCursorMode;
|
int m_LockCursorMode;
|
||||||
bool m_ActiveOnRelease;
|
bool m_ActiveOnRelease;
|
||||||
|
|
|
@ -39,7 +39,7 @@ ActionDialog::ActionDialog(QWidget* parent, ServerConfig& config, Hotkey& hotkey
|
||||||
|
|
||||||
// work around Qt Designer's lack of a QButtonGroup; we need it to get
|
// work around Qt Designer's lack of a QButtonGroup; we need it to get
|
||||||
// at the button id of the checked radio button
|
// at the button id of the checked radio button
|
||||||
QRadioButton* const typeButtons[] = { m_pRadioPress, m_pRadioRelease, m_pRadioPressAndRelease, m_pRadioSwitchToScreen, m_pRadioToggleScreen, m_pRadioSwitchInDirection, m_pRadioLockCursorToScreen };
|
QRadioButton* const typeButtons[] = { m_pRadioPress, m_pRadioRelease, m_pRadioPressAndRelease, m_pRadioSwitchToScreen, m_pRadioToggleScreen, m_pRadioSwitchInDirection, m_pRadioLockCursorToScreen, m_pRadioUserScript };
|
||||||
|
|
||||||
for (unsigned int i = 0; i < sizeof(typeButtons) / sizeof(typeButtons[0]); i++)
|
for (unsigned int i = 0; i < sizeof(typeButtons) / sizeof(typeButtons[0]); i++)
|
||||||
m_pButtonGroupType->addButton(typeButtons[i], i);
|
m_pButtonGroupType->addButton(typeButtons[i], i);
|
||||||
|
@ -49,6 +49,7 @@ ActionDialog::ActionDialog(QWidget* parent, ServerConfig& config, Hotkey& hotkey
|
||||||
m_pButtonGroupType->button(m_Action.type())->setChecked(true);
|
m_pButtonGroupType->button(m_Action.type())->setChecked(true);
|
||||||
m_pComboSwitchInDirection->setCurrentIndex(m_Action.switchDirection());
|
m_pComboSwitchInDirection->setCurrentIndex(m_Action.switchDirection());
|
||||||
m_pComboLockCursorToScreen->setCurrentIndex(m_Action.lockCursorMode());
|
m_pComboLockCursorToScreen->setCurrentIndex(m_Action.lockCursorMode());
|
||||||
|
m_pUserScriptCommand->setText(m_Action.userScriptCommand());
|
||||||
|
|
||||||
if (m_Action.activeOnRelease())
|
if (m_Action.activeOnRelease())
|
||||||
m_pRadioHotkeyReleased->setChecked(true);
|
m_pRadioHotkeyReleased->setChecked(true);
|
||||||
|
@ -93,6 +94,7 @@ void ActionDialog::accept()
|
||||||
m_Action.setSwitchDirection(m_pComboSwitchInDirection->currentIndex());
|
m_Action.setSwitchDirection(m_pComboSwitchInDirection->currentIndex());
|
||||||
m_Action.setLockCursorMode(m_pComboLockCursorToScreen->currentIndex());
|
m_Action.setLockCursorMode(m_pComboLockCursorToScreen->currentIndex());
|
||||||
m_Action.setActiveOnRelease(m_pRadioHotkeyReleased->isChecked());
|
m_Action.setActiveOnRelease(m_pRadioHotkeyReleased->isChecked());
|
||||||
|
m_Action.setUserScriptCommand(m_pUserScriptCommand->text());
|
||||||
|
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>372</width>
|
<width>372</width>
|
||||||
<height>484</height>
|
<height>508</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -250,6 +250,37 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="m_pRadioUserScript">
|
||||||
|
<property name="text">
|
||||||
|
<string>User Script</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="m_pUserScriptCommand">
|
||||||
|
<property name="text">
|
||||||
|
<string>script1</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -588,5 +619,53 @@
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_pRadioUserScript</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>m_pUserScriptCommand</receiver>
|
||||||
|
<slot>setEnabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>63</x>
|
||||||
|
<y>385</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>291</x>
|
||||||
|
<y>385</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_pRadioUserScript</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>m_pKeySequenceWidgetHotkey</receiver>
|
||||||
|
<slot>setDisabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>63</x>
|
||||||
|
<y>385</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>185</x>
|
||||||
|
<y>118</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_pRadioUserScript</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>m_pGroupBoxScreens</receiver>
|
||||||
|
<slot>setDisabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>63</x>
|
||||||
|
<y>385</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>185</x>
|
||||||
|
<y>189</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
</connections>
|
</connections>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
|
@ -1244,6 +1244,20 @@ void Config::parseAction(ConfigReadContext& s, const std::string& name,
|
||||||
action = new InputFilter::KeyboardBroadcastAction(m_events, mode, screens);
|
action = new InputFilter::KeyboardBroadcastAction(m_events, mode, screens);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (name == "userScript") {
|
||||||
|
if (args.size() != 1) {
|
||||||
|
throw XConfigRead(s, "syntax for action: userScript(scriptCommand)");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string scriptCommand = args[0];
|
||||||
|
|
||||||
|
if (scriptCommand.empty()) {
|
||||||
|
throw XConfigRead(s, "bad script command in userScript");
|
||||||
|
}
|
||||||
|
|
||||||
|
action = new InputFilter::UserScriptAction(m_events, scriptCommand);
|
||||||
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
throw XConfigRead(s, "unknown action argument \"%{1}\"", name);
|
throw XConfigRead(s, "unknown action argument \"%{1}\"", name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -660,6 +660,53 @@ InputFilter::MouseButtonAction::formatName() const
|
||||||
return (m_press ? "mouseDown" : "mouseUp");
|
return (m_press ? "mouseDown" : "mouseUp");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
InputFilter::UserScriptAction::UserScriptAction(IEventQueue* events,
|
||||||
|
const std::string& scriptCommand) :
|
||||||
|
m_scriptCommand(scriptCommand),
|
||||||
|
m_events(events)
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string InputFilter::UserScriptAction::getScriptCommand() const
|
||||||
|
{
|
||||||
|
return m_scriptCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputFilter::Action*
|
||||||
|
InputFilter::UserScriptAction::clone() const
|
||||||
|
{
|
||||||
|
return new UserScriptAction(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string InputFilter::UserScriptAction::format() const
|
||||||
|
{
|
||||||
|
return barrier::string::sprintf("userScript(%s)", m_scriptCommand.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
InputFilter::UserScriptAction::perform(const Event& event)
|
||||||
|
{
|
||||||
|
// pick screen name. if m_screen is empty then use the screen from
|
||||||
|
// event if it has one.
|
||||||
|
std::string scriptCommand = m_scriptCommand;
|
||||||
|
if (scriptCommand.empty()) {
|
||||||
|
LOG((CLOG_ERR "script ID empty"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// exec script
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
std::string s = barrier::string::sprintf(R"(sh -c '%s')", scriptCommand.c_str());
|
||||||
|
#else
|
||||||
|
std::string s = barrier::string::sprintf(R"(cmd.exe /C "%s")", scriptCommand.c_str());
|
||||||
|
|
||||||
|
#endif
|
||||||
|
LOG((CLOG_DEBUG "%s",s.c_str()));
|
||||||
|
system(s.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// InputFilter::Rule
|
// InputFilter::Rule
|
||||||
//
|
//
|
||||||
|
|
|
@ -270,6 +270,23 @@ public:
|
||||||
IEventQueue* m_events;
|
IEventQueue* m_events;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// UserScriptAction
|
||||||
|
class UserScriptAction : public Action {
|
||||||
|
public:
|
||||||
|
UserScriptAction(IEventQueue* events, const std::string& scriptCommand);
|
||||||
|
|
||||||
|
std::string getScriptCommand() const;
|
||||||
|
|
||||||
|
// Action overrides
|
||||||
|
virtual Action* clone() const;
|
||||||
|
virtual String format() const;
|
||||||
|
virtual void perform(const Event&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_scriptCommand;
|
||||||
|
IEventQueue* m_events;
|
||||||
|
};
|
||||||
|
|
||||||
class Rule {
|
class Rule {
|
||||||
public:
|
public:
|
||||||
Rule();
|
Rule();
|
||||||
|
|
Loading…
Reference in New Issue