aboutsummaryrefslogtreecommitdiffstats
path: root/vncviewer/OptionsDialog.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vncviewer/OptionsDialog.cxx')
-rw-r--r--vncviewer/OptionsDialog.cxx382
1 files changed, 282 insertions, 100 deletions
diff --git a/vncviewer/OptionsDialog.cxx b/vncviewer/OptionsDialog.cxx
index c5f21b24..3ba6fba1 100644
--- a/vncviewer/OptionsDialog.cxx
+++ b/vncviewer/OptionsDialog.cxx
@@ -1,4 +1,4 @@
-/* Copyright 2011-2021 Pierre Ossman <ossman@cendio.se> for Cendio AB
+/* Copyright 2011-2025 Pierre Ossman <ossman@cendio.se> for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,6 +24,8 @@
#include <stdlib.h>
#include <list>
+#include <core/string.h>
+
#include <rfb/encodings.h>
#if defined(HAVE_GNUTLS) || defined(HAVE_NETTLE)
@@ -35,8 +37,8 @@
#endif
#include "OptionsDialog.h"
+#include "ShortcutHandler.h"
#include "i18n.h"
-#include "menukey.h"
#include "parameters.h"
#include "fltk/layout.h"
@@ -44,18 +46,21 @@
#include "fltk/Fl_Monitor_Arrangement.h"
#include "fltk/Fl_Navigation.h"
+#ifdef __APPLE__
+#include "cocoa.h"
+#endif
+
#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
#include <FL/Fl_Tabs.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Check_Button.H>
#include <FL/Fl_Return_Button.H>
#include <FL/Fl_Round_Button.H>
+#include <FL/Fl_Toggle_Button.H>
#include <FL/Fl_Int_Input.H>
#include <FL/Fl_Choice.H>
-using namespace std;
-using namespace rfb;
-
std::map<OptionsCallback*, void*> OptionsDialog::callbacks;
static std::set<OptionsDialog *> instances;
@@ -85,6 +90,7 @@ OptionsDialog::OptionsDialog()
createCompressionPage(tx, ty, tw, th);
createSecurityPage(tx, ty, tw, th);
createInputPage(tx, ty, tw, th);
+ createShortcutsPage(tx, ty, tw, th);
createDisplayPage(tx, ty, tw, th);
createMiscPage(tx, ty, tw, th);
}
@@ -162,27 +168,18 @@ void OptionsDialog::loadOptions(void)
/* Compression */
autoselectCheckbox->value(autoSelect);
- int encNum = encodingNum(preferredEncoding);
-
- switch (encNum) {
- case encodingTight:
+ if (preferredEncoding == "Tight")
tightButton->setonly();
- break;
- case encodingZRLE:
+ else if (preferredEncoding == "ZRLE")
zrleButton->setonly();
- break;
- case encodingHextile:
+ else if (preferredEncoding == "Hextile")
hextileButton->setonly();
- break;
#ifdef HAVE_H264
- case encodingH264:
+ else if (preferredEncoding == "H.264")
h264Button->setonly();
- break;
#endif
- case encodingRaw:
+ else if (preferredEncoding == "Raw")
rawButton->setonly();
- break;
- }
if (fullColour)
fullcolorCheckbox->setonly();
@@ -215,11 +212,11 @@ void OptionsDialog::loadOptions(void)
#if defined(HAVE_GNUTLS) || defined(HAVE_NETTLE)
/* Security */
- Security security(SecurityClient::secTypes);
+ rfb::Security security(rfb::SecurityClient::secTypes);
- list<uint8_t> secTypes;
+ std::list<uint8_t> secTypes;
- list<uint32_t> secTypesExt;
+ std::list<uint32_t> secTypesExt;
encNoneCheckbox->value(false);
#ifdef HAVE_GNUTLS
@@ -237,11 +234,11 @@ void OptionsDialog::loadOptions(void)
secTypes = security.GetEnabledSecTypes();
for (uint8_t type : secTypes) {
switch (type) {
- case secTypeNone:
+ case rfb::secTypeNone:
encNoneCheckbox->value(true);
authNoneCheckbox->value(true);
break;
- case secTypeVncAuth:
+ case rfb::secTypeVncAuth:
encNoneCheckbox->value(true);
authVncCheckbox->value(true);
break;
@@ -251,49 +248,49 @@ void OptionsDialog::loadOptions(void)
secTypesExt = security.GetEnabledExtSecTypes();
for (uint32_t type : secTypesExt) {
switch (type) {
- case secTypePlain:
+ case rfb::secTypePlain:
encNoneCheckbox->value(true);
authPlainCheckbox->value(true);
break;
#ifdef HAVE_GNUTLS
- case secTypeTLSNone:
+ case rfb::secTypeTLSNone:
encTLSCheckbox->value(true);
authNoneCheckbox->value(true);
break;
- case secTypeTLSVnc:
+ case rfb::secTypeTLSVnc:
encTLSCheckbox->value(true);
authVncCheckbox->value(true);
break;
- case secTypeTLSPlain:
+ case rfb::secTypeTLSPlain:
encTLSCheckbox->value(true);
authPlainCheckbox->value(true);
break;
- case secTypeX509None:
+ case rfb::secTypeX509None:
encX509Checkbox->value(true);
authNoneCheckbox->value(true);
break;
- case secTypeX509Vnc:
+ case rfb::secTypeX509Vnc:
encX509Checkbox->value(true);
authVncCheckbox->value(true);
break;
- case secTypeX509Plain:
+ case rfb::secTypeX509Plain:
encX509Checkbox->value(true);
authPlainCheckbox->value(true);
break;
#endif
#ifdef HAVE_NETTLE
- case secTypeRA2:
- case secTypeRA256:
+ case rfb::secTypeRA2:
+ case rfb::secTypeRA256:
encRSAAESCheckbox->value(true);
authVncCheckbox->value(true);
authPlainCheckbox->value(true);
break;
- case secTypeRA2ne:
- case secTypeRAne256:
+ case rfb::secTypeRA2ne:
+ case rfb::secTypeRAne256:
authVncCheckbox->value(true);
/* fall through */
- case secTypeDH:
- case secTypeMSLogonII:
+ case rfb::secTypeDH:
+ case rfb::secTypeMSLogonII:
encNoneCheckbox->value(true);
authPlainCheckbox->value(true);
break;
@@ -303,16 +300,14 @@ void OptionsDialog::loadOptions(void)
}
#ifdef HAVE_GNUTLS
- caInput->value(CSecurityTLS::X509CA);
- crlInput->value(CSecurityTLS::X509CRL);
+ caInput->value(rfb::CSecurityTLS::X509CA);
+ crlInput->value(rfb::CSecurityTLS::X509CRL);
handleX509(encX509Checkbox, this);
#endif
#endif
/* Input */
- const char *menuKeyBuf;
-
viewOnlyCheckbox->value(viewOnly);
emulateMBCheckbox->value(emulateMiddleButton);
acceptClipboardCheckbox->value(acceptClipboard);
@@ -325,34 +320,48 @@ void OptionsDialog::loadOptions(void)
#endif
systemKeysCheckbox->value(fullscreenSystemKeys);
- menuKeyChoice->value(0);
+ /* Keyboard shortcuts */
+ unsigned modifierMask;
+
+ modifierMask = 0;
+ for (core::EnumListEntry key : shortcutModifiers)
+ modifierMask |= ShortcutHandler::parseModifier(key.getValueStr().c_str());
+
+ ctrlButton->value(modifierMask & ShortcutHandler::Control);
+ shiftButton->value(modifierMask & ShortcutHandler::Shift);
+ altButton->value(modifierMask & ShortcutHandler::Alt);
+ superButton->value(modifierMask & ShortcutHandler::Super);
- menuKeyBuf = menuKey;
- for (int idx = 0; idx < getMenuKeySymbolCount(); idx++)
- if (!strcmp(getMenuKeySymbols()[idx].name, menuKeyBuf))
- menuKeyChoice->value(idx + 1);
+ handleModifier(nullptr, this);
/* Display */
if (!fullScreen) {
windowedButton->setonly();
} else {
- if (!strcasecmp(fullScreenMode, "all")) {
+ if (fullScreenMode == "all") {
allMonitorsButton->setonly();
- } else if (!strcasecmp(fullScreenMode, "selected")) {
+ } else if (fullScreenMode == "selected") {
selectedMonitorsButton->setonly();
} else {
currentMonitorButton->setonly();
}
}
- monitorArrangement->value(fullScreenSelectedMonitors.getParam());
+ monitorArrangement->value(fullScreenSelectedMonitors.getMonitors());
handleFullScreenMode(selectedMonitorsButton, this);
/* Misc. */
sharedCheckbox->value(shared);
reconnectCheckbox->value(reconnectOnError);
- dotCursorCheckbox->value(dotWhenNoCursor);
+ alwaysCursorCheckbox->value(alwaysCursor);
+ if (cursorType == "system") {
+ cursorTypeChoice->value(1);
+ } else {
+ // Default
+ cursorTypeChoice->value(0);
+ }
+ handleAlwaysCursor(alwaysCursorCheckbox, this);
}
@@ -362,17 +371,17 @@ void OptionsDialog::storeOptions(void)
autoSelect.setParam(autoselectCheckbox->value());
if (tightButton->value())
- preferredEncoding.setParam(encodingName(encodingTight));
+ preferredEncoding.setParam(rfb::encodingName(rfb::encodingTight));
else if (zrleButton->value())
- preferredEncoding.setParam(encodingName(encodingZRLE));
+ preferredEncoding.setParam(rfb::encodingName(rfb::encodingZRLE));
else if (hextileButton->value())
- preferredEncoding.setParam(encodingName(encodingHextile));
+ preferredEncoding.setParam(rfb::encodingName(rfb::encodingHextile));
#ifdef HAVE_H264
else if (h264Button->value())
- preferredEncoding.setParam(encodingName(encodingH264));
+ preferredEncoding.setParam(rfb::encodingName(rfb::encodingH264));
#endif
else if (rawButton->value())
- preferredEncoding.setParam(encodingName(encodingRaw));
+ preferredEncoding.setParam(rfb::encodingName(rfb::encodingRaw));
fullColour.setParam(fullcolorCheckbox->value());
if (verylowcolorCheckbox->value())
@@ -389,26 +398,26 @@ void OptionsDialog::storeOptions(void)
#if defined(HAVE_GNUTLS) || defined(HAVE_NETTLE)
/* Security */
- Security security;
+ rfb::Security security;
/* Process security types which don't use encryption */
if (encNoneCheckbox->value()) {
if (authNoneCheckbox->value())
- security.EnableSecType(secTypeNone);
+ security.EnableSecType(rfb::secTypeNone);
if (authVncCheckbox->value()) {
- security.EnableSecType(secTypeVncAuth);
+ security.EnableSecType(rfb::secTypeVncAuth);
#ifdef HAVE_NETTLE
- security.EnableSecType(secTypeRA2ne);
- security.EnableSecType(secTypeRAne256);
+ security.EnableSecType(rfb::secTypeRA2ne);
+ security.EnableSecType(rfb::secTypeRAne256);
#endif
}
if (authPlainCheckbox->value()) {
- security.EnableSecType(secTypePlain);
+ security.EnableSecType(rfb::secTypePlain);
#ifdef HAVE_NETTLE
- security.EnableSecType(secTypeRA2ne);
- security.EnableSecType(secTypeRAne256);
- security.EnableSecType(secTypeDH);
- security.EnableSecType(secTypeMSLogonII);
+ security.EnableSecType(rfb::secTypeRA2ne);
+ security.EnableSecType(rfb::secTypeRAne256);
+ security.EnableSecType(rfb::secTypeDH);
+ security.EnableSecType(rfb::secTypeMSLogonII);
#endif
}
}
@@ -417,34 +426,34 @@ void OptionsDialog::storeOptions(void)
/* Process security types which use TLS encryption */
if (encTLSCheckbox->value()) {
if (authNoneCheckbox->value())
- security.EnableSecType(secTypeTLSNone);
+ security.EnableSecType(rfb::secTypeTLSNone);
if (authVncCheckbox->value())
- security.EnableSecType(secTypeTLSVnc);
+ security.EnableSecType(rfb::secTypeTLSVnc);
if (authPlainCheckbox->value())
- security.EnableSecType(secTypeTLSPlain);
+ security.EnableSecType(rfb::secTypeTLSPlain);
}
/* Process security types which use X509 encryption */
if (encX509Checkbox->value()) {
if (authNoneCheckbox->value())
- security.EnableSecType(secTypeX509None);
+ security.EnableSecType(rfb::secTypeX509None);
if (authVncCheckbox->value())
- security.EnableSecType(secTypeX509Vnc);
+ security.EnableSecType(rfb::secTypeX509Vnc);
if (authPlainCheckbox->value())
- security.EnableSecType(secTypeX509Plain);
+ security.EnableSecType(rfb::secTypeX509Plain);
}
- CSecurityTLS::X509CA.setParam(caInput->value());
- CSecurityTLS::X509CRL.setParam(crlInput->value());
+ rfb::CSecurityTLS::X509CA.setParam(caInput->value());
+ rfb::CSecurityTLS::X509CRL.setParam(crlInput->value());
#endif
#ifdef HAVE_NETTLE
if (encRSAAESCheckbox->value()) {
- security.EnableSecType(secTypeRA2);
- security.EnableSecType(secTypeRA256);
+ security.EnableSecType(rfb::secTypeRA2);
+ security.EnableSecType(rfb::secTypeRA256);
}
#endif
- SecurityClient::secTypes.setParam(security.ToString());
+ rfb::SecurityClient::secTypes.setParam(security.ToString());
#endif
/* Input */
@@ -460,11 +469,23 @@ void OptionsDialog::storeOptions(void)
#endif
fullscreenSystemKeys.setParam(systemKeysCheckbox->value());
- if (menuKeyChoice->value() == 0)
- menuKey.setParam("");
- else {
- menuKey.setParam(menuKeyChoice->text());
- }
+ /* Keyboard shortcuts */
+ std::list<std::string> modifierList;
+
+ if (ctrlButton->value())
+ modifierList.push_back(
+ ShortcutHandler::modifierString(ShortcutHandler::Control));
+ if (shiftButton->value())
+ modifierList.push_back(
+ ShortcutHandler::modifierString(ShortcutHandler::Shift));
+ if (altButton->value())
+ modifierList.push_back(
+ ShortcutHandler::modifierString(ShortcutHandler::Alt));
+ if (superButton->value())
+ modifierList.push_back(
+ ShortcutHandler::modifierString(ShortcutHandler::Super));
+
+ shortcutModifiers.setParam(modifierList);
/* Display */
if (windowedButton->value()) {
@@ -481,12 +502,19 @@ void OptionsDialog::storeOptions(void)
}
}
- fullScreenSelectedMonitors.setParam(monitorArrangement->value());
+ fullScreenSelectedMonitors.setMonitors(monitorArrangement->value());
/* Misc. */
shared.setParam(sharedCheckbox->value());
reconnectOnError.setParam(reconnectCheckbox->value());
- dotWhenNoCursor.setParam(dotCursorCheckbox->value());
+ alwaysCursor.setParam(alwaysCursorCheckbox->value());
+
+ if (cursorTypeChoice->value() == 1) {
+ cursorType.setParam("System");
+ } else {
+ // Default
+ cursorType.setParam("Dot");
+ }
std::map<OptionsCallback*, void*>::const_iterator iter;
@@ -840,11 +868,23 @@ void OptionsDialog::createInputPage(int tx, int ty, int tw, int th)
_("Emulate middle mouse button")));
ty += CHECK_HEIGHT + TIGHT_MARGIN;
- dotCursorCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
- CHECK_MIN_WIDTH,
- CHECK_HEIGHT,
- _("Show dot when no cursor")));
+ alwaysCursorCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("Show local cursor when not provided by server")));
+ alwaysCursorCheckbox->callback(handleAlwaysCursor, this);
ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
+ /* Cursor type */
+ cursorTypeChoice = new Fl_Choice(LBLLEFT(tx, ty, 150, CHOICE_HEIGHT, _("Cursor type")));
+
+ fltk_menu_add(cursorTypeChoice, _("Dot"), 0, nullptr, nullptr, 0);
+ fltk_menu_add(cursorTypeChoice, _("System"), 0, nullptr, nullptr, 0);
+
+ fltk_adjust_choice(cursorTypeChoice);
+
+ ty += CHOICE_HEIGHT + TIGHT_MARGIN;
+
}
ty -= TIGHT_MARGIN;
@@ -868,19 +908,11 @@ void OptionsDialog::createInputPage(int tx, int ty, int tw, int th)
tx += INDENT;
ty += TIGHT_MARGIN;
- systemKeysCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
- CHECK_MIN_WIDTH,
- CHECK_HEIGHT,
- _("Pass system keys directly to server (full screen)")));
+ systemKeysCheckbox = new Fl_Check_Button(
+ LBLRIGHT(tx, ty, CHECK_MIN_WIDTH, CHECK_HEIGHT,
+ _("Always send all keyboard input in full screen")));
+ systemKeysCheckbox->callback(handleSystemKeys, this);
ty += CHECK_HEIGHT + TIGHT_MARGIN;
-
- menuKeyChoice = new Fl_Choice(LBLLEFT(tx, ty, 150, CHOICE_HEIGHT, _("Menu key")));
-
- fltk_menu_add(menuKeyChoice, _("None"), 0, nullptr, nullptr, FL_MENU_DIVIDER);
- for (int idx = 0; idx < getMenuKeySymbolCount(); idx++)
- fltk_menu_add(menuKeyChoice, getMenuKeySymbols()[idx].name, 0, nullptr, nullptr, 0);
-
- ty += CHOICE_HEIGHT + TIGHT_MARGIN;
}
ty -= TIGHT_MARGIN;
@@ -949,6 +981,76 @@ void OptionsDialog::createInputPage(int tx, int ty, int tw, int th)
}
+void OptionsDialog::createShortcutsPage(int tx, int ty, int tw, int th)
+{
+ Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Keyboard shortcuts"));
+
+ tx += OUTER_MARGIN;
+ ty += OUTER_MARGIN;
+
+ Fl_Box *intro = new Fl_Box(tx, ty, tw - OUTER_MARGIN * 2, INPUT_HEIGHT);
+ intro->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
+ intro->label(_("Modifier keys for keyboard shortcuts:"));
+
+ ty += INPUT_HEIGHT + INNER_MARGIN;
+
+ int width;
+
+ width = (tw - OUTER_MARGIN * 2 - INNER_MARGIN * 3) / 4;
+
+ ctrlButton = new Fl_Toggle_Button(tx, ty,
+ /*
+ * TRANSLATORS: This refers to the
+ * keyboard key
+ * */
+ width, BUTTON_HEIGHT, _("Ctrl"));
+ ctrlButton->selection_color(FL_SELECTION_COLOR);
+ ctrlButton->callback(handleModifier, this);
+ shiftButton = new Fl_Toggle_Button(tx + width + INNER_MARGIN, ty,
+ /*
+ * TRANSLATORS: This refers to the
+ * keyboard key
+ * */
+ width, BUTTON_HEIGHT, _("Shift"));
+ shiftButton->selection_color(FL_SELECTION_COLOR);
+ shiftButton->callback(handleModifier, this);
+ altButton = new Fl_Toggle_Button(tx + width * 2 + INNER_MARGIN * 2, ty,
+ /*
+ * TRANSLATORS: This refers to the
+ * keyboard key
+ * */
+ width, BUTTON_HEIGHT, _("Alt"));
+ altButton->selection_color(FL_SELECTION_COLOR);
+ altButton->callback(handleModifier, this);
+ superButton = new Fl_Toggle_Button(tx + width * 3 + INNER_MARGIN * 3, ty,
+ /*
+ * TRANSLATORS: This refers to the
+ * keyboard key
+ * */
+ width, BUTTON_HEIGHT, _("Win"));
+ superButton->selection_color(FL_SELECTION_COLOR);
+ superButton->callback(handleModifier, this);
+
+#ifdef __APPLE__
+ /* TRANSLATORS: This refers to the keyboard key */
+ ctrlButton->label(_("⌃ Ctrl"));
+ /* TRANSLATORS: This refers to the keyboard key */
+ shiftButton->label(_("⇧ Shift"));
+ /* TRANSLATORS: This refers to the keyboard key */
+ altButton->label(_("⌥ Option"));
+ /* TRANSLATORS: This refers to the keyboard key */
+ superButton->label(_("⌘ Cmd"));
+#endif
+
+ ty += BUTTON_HEIGHT + INNER_MARGIN;
+
+ shortcutsText = new Fl_Box(tx, ty, tw - OUTER_MARGIN * 2, th - ty - OUTER_MARGIN);
+ shortcutsText->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
+
+ group->end();
+}
+
+
void OptionsDialog::createDisplayPage(int tx, int ty, int tw, int th)
{
Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Display"));
@@ -1117,6 +1219,20 @@ void OptionsDialog::handleRSAAES(Fl_Widget* /*widget*/, void *data)
}
+void OptionsDialog::handleSystemKeys(Fl_Widget* /*widget*/, void* data)
+{
+#ifdef __APPLE__
+ OptionsDialog* dialog = (OptionsDialog*)data;
+
+ // Pop up the access dialog if needed
+ if (dialog->systemKeysCheckbox->value())
+ cocoa_is_trusted(true);
+#else
+ (void)data;
+#endif
+}
+
+
void OptionsDialog::handleClipboard(Fl_Widget* /*widget*/, void *data)
{
(void)data;
@@ -1134,6 +1250,61 @@ void OptionsDialog::handleClipboard(Fl_Widget* /*widget*/, void *data)
#endif
}
+void OptionsDialog::handleModifier(Fl_Widget* /*widget*/, void *data)
+{
+ OptionsDialog *dialog = (OptionsDialog*)data;
+ unsigned mask;
+
+ mask = 0;
+ if (dialog->ctrlButton->value())
+ mask |= ShortcutHandler::Control;
+ if (dialog->shiftButton->value())
+ mask |= ShortcutHandler::Shift;
+ if (dialog->altButton->value())
+ mask |= ShortcutHandler::Alt;
+ if (dialog->superButton->value())
+ mask |= ShortcutHandler::Super;
+
+ if (mask == 0) {
+ dialog->shortcutsText->copy_label(
+ _("All keyboard shortcuts are disabled."));
+ } else {
+ char prefix[256];
+ char prefix_noplus[256];
+
+ std::string label;
+
+ strcpy(prefix, ShortcutHandler::modifierPrefix(mask));
+ strcpy(prefix_noplus, ShortcutHandler::modifierPrefix(mask, true));
+
+ label += core::format(
+ _("To release keyboard control from the session, press %s."),
+ prefix_noplus);
+ label += "\n\n";
+
+ label += core::format(
+ _("To pass all keyboard input to the session, press %sG."),
+ prefix);
+ label += "\n\n";
+
+ label += core::format(
+ _("To toggle full-screen mode, press %sEnter."), prefix);
+ label += "\n\n";
+
+ label += core::format(
+ _("To open the session context menu, press %sM."), prefix);
+ label += "\n\n";
+
+ label += core::format(
+ _("To send a key combination that includes %s directly to the "
+ "session, press %sSpace, release the space bar without "
+ "releasing %s, and press the desired key."),
+ prefix_noplus, prefix, prefix_noplus);
+
+ dialog->shortcutsText->copy_label(label.c_str());
+ }
+}
+
void OptionsDialog::handleFullScreenMode(Fl_Widget* /*widget*/, void *data)
{
OptionsDialog *dialog = (OptionsDialog*)data;
@@ -1184,5 +1355,16 @@ void OptionsDialog::handleScreenConfigTimeout(void *data)
assert(self);
- self->monitorArrangement->value(fullScreenSelectedMonitors.getParam());
+ self->monitorArrangement->value(fullScreenSelectedMonitors.getMonitors());
+}
+
+void OptionsDialog::handleAlwaysCursor(Fl_Widget* /*widget*/, void *data)
+{
+ OptionsDialog *dialog = (OptionsDialog*)data;
+
+ if (dialog->alwaysCursorCheckbox->value()) {
+ dialog->cursorTypeChoice->activate();
+ } else {
+ dialog->cursorTypeChoice->deactivate();
+ }
}