]> source.dussan.org Git - tigervnc.git/commitdiff
Update MonitorArrangement widget after change 1405/head
authorSamuel Mannehed <samuel@cendio.se>
Fri, 7 Jan 2022 17:46:17 +0000 (18:46 +0100)
committerSamuel Mannehed <samuel@cendio.se>
Mon, 10 Jan 2022 15:04:34 +0000 (16:04 +0100)
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
vncviewer/OptionsDialog.h

index f7cc774dee6d4c3c76fba388fb95837da1da8bca..3250038be11313c7c8b8646e6133938534c5b1d7 100644 (file)
@@ -20,8 +20,8 @@
 #include <config.h>
 #endif
 
+#include <assert.h>
 #include <stdlib.h>
-
 #include <list>
 
 #include <rdr/types.h>
@@ -40,6 +40,7 @@
 #include "parameters.h"
 #include "MonitorArrangement.h"
 
+#include <FL/Fl.H>
 #include <FL/Fl_Tabs.H>
 #include <FL/Fl_Button.H>
 #include <FL/Fl_Check_Button.H>
@@ -54,6 +55,8 @@ using namespace rfb;
 
 std::map<OptionsCallback*, void*> OptionsDialog::callbacks;
 
+static std::set<OptionsDialog *> 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<OptionsDialog *>::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());
+}
index fe39f19255b8648f3a0e6a0e311ae50ddab5a229..6ed7b3f92c47cf02ae34c083810fb8861cb4bcd8 100644 (file)
@@ -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