From 6a1de9092d8587a1a8e917d98c99dbc3ec74edf0 Mon Sep 17 00:00:00 2001 From: Samuel Mannehed Date: Fri, 7 Jan 2022 18:46:17 +0100 Subject: [PATCH] Update MonitorArrangement widget after change If the options dialog was open when a screen configuration happened the widget could get out of sync from the settings. A scenario when this happened was: 1) 3 monitors, fullscreen selected on the two right-most screens 2) disconnect the left-most screen (the one not selected) In this case, using GNOME, vncviewer would appear in fullscreen on the right of the two remaining monitors, but the widget would show both monitors selected. The reason was that the MonitorArragement index doesn't work the same way as FLTK's screen index. It's debatable how vncviewer should behave here, but the GUI should at least match the actual setting. --- vncviewer/OptionsDialog.cxx | 38 ++++++++++++++++++++++++++++++++++++- vncviewer/OptionsDialog.h | 4 ++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/vncviewer/OptionsDialog.cxx b/vncviewer/OptionsDialog.cxx index f7cc774d..3250038b 100644 --- a/vncviewer/OptionsDialog.cxx +++ b/vncviewer/OptionsDialog.cxx @@ -20,8 +20,8 @@ #include #endif +#include #include - #include #include @@ -40,6 +40,7 @@ #include "parameters.h" #include "MonitorArrangement.h" +#include #include #include #include @@ -54,6 +55,8 @@ using namespace rfb; std::map OptionsDialog::callbacks; +static std::set instances; + OptionsDialog::OptionsDialog() : Fl_Window(450, 460, _("VNC Viewer: Connection Options")) { @@ -92,11 +95,19 @@ OptionsDialog::OptionsDialog() callback(this->handleCancel, this); set_modal(); + + if (instances.size() == 0) + Fl::add_handler(fltk_event_handler); + instances.insert(this); } OptionsDialog::~OptionsDialog() { + instances.erase(this); + + if (instances.size() == 0) + Fl::remove_handler(fltk_event_handler); } @@ -1031,3 +1042,28 @@ void OptionsDialog::handleOK(Fl_Widget *widget, void *data) dialog->storeOptions(); } + +int OptionsDialog::fltk_event_handler(int event) +{ + std::set::iterator iter; + + if (event != FL_SCREEN_CONFIGURATION_CHANGED) + return 0; + + // Refresh monitor arrangement widget to match the parameter settings after + // screen configuration has changed. The MonitorArrangement index doesn't work + // the same way as the FLTK screen index. + for (iter = instances.begin(); iter != instances.end(); iter++) + Fl::add_timeout(0, handleScreenConfigTimeout, (*iter)); + + return 0; +} + +void OptionsDialog::handleScreenConfigTimeout(void *data) +{ + OptionsDialog *self = (OptionsDialog *)data; + + assert(self); + + self->monitorArrangement->set(fullScreenSelectedMonitors.getParam()); +} diff --git a/vncviewer/OptionsDialog.h b/vncviewer/OptionsDialog.h index fe39f192..6ed7b3f9 100644 --- a/vncviewer/OptionsDialog.h +++ b/vncviewer/OptionsDialog.h @@ -135,6 +135,10 @@ protected: /* Misc. */ Fl_Check_Button *sharedCheckbox; Fl_Check_Button *reconnectCheckbox; + +private: + static int fltk_event_handler(int event); + static void handleScreenConfigTimeout(void *data); }; #endif -- 2.39.5