aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo Lundin <hugo@lundin.dev>2021-07-16 16:31:16 +0200
committerHugo Lundin <hugo@lundin.dev>2021-07-16 16:31:16 +0200
commit11ca86b9432bfb1e7d2ba586b4dc6da60329bf92 (patch)
tree02fdcf26f12bb4578e0ab27cf53fd717bc58955f
parent51dfeecd8ec102d69788a8130a19c5d21f566f3f (diff)
downloadtigervnc-11ca86b9432bfb1e7d2ba586b4dc6da60329bf92.tar.gz
tigervnc-11ca86b9432bfb1e7d2ba586b4dc6da60329bf92.zip
Refresh MonitorArrangement on configuration change
MonitorArrangement (in the options dialog) never changes when the system monitor configuration changes. Therefore, the user can get into a state where the reality doesn't match what is shown (when a monitor is added/removed, resolution or position changed etc). All these changes triggers an event in FLTK (FL_SCREEN_CONFIGURATION_CHANGED). This commit adds an event handler in MonitorArrangement and refreshes the widget whenever that event occurs. Because Fl_Handler does not have a void*-argument (and we must be able to access the widget from our handler callback) a static set of instances have been added, which all will receive the events.
-rw-r--r--vncviewer/MonitorArrangement.cxx45
-rw-r--r--vncviewer/MonitorArrangement.h4
2 files changed, 49 insertions, 0 deletions
diff --git a/vncviewer/MonitorArrangement.cxx b/vncviewer/MonitorArrangement.cxx
index 83a53d38..2a7bfad6 100644
--- a/vncviewer/MonitorArrangement.cxx
+++ b/vncviewer/MonitorArrangement.cxx
@@ -52,6 +52,7 @@
#include "i18n.h"
#include "MonitorArrangement.h"
+static std::set<MonitorArrangement *> instances;
static rfb::LogWriter vlog("MonitorArrangement");
static const Fl_Boxtype FL_CHECKERED_BOX = FL_FREE_BOXTYPE;
@@ -65,6 +66,10 @@ MonitorArrangement::MonitorArrangement(
// Used for required monitors.
Fl::set_boxtype(FL_CHECKERED_BOX, checkered_pattern_draw, 0, 0, 0, 0);
+ if (instances.size() == 0)
+ Fl::add_handler(fltk_event_handler);
+ instances.insert(this);
+
box(FL_DOWN_BOX);
color(fl_lighter(FL_BACKGROUND_COLOR));
layout();
@@ -73,7 +78,10 @@ MonitorArrangement::MonitorArrangement(
MonitorArrangement::~MonitorArrangement()
{
+ instances.erase(this);
+ if (instances.size() == 0)
+ Fl::remove_handler(fltk_event_handler);
}
std::set<int> MonitorArrangement::get()
@@ -142,6 +150,25 @@ void MonitorArrangement::layout()
m_monitors[i]->copy_tooltip(description(i).c_str());
}
+void MonitorArrangement::refresh()
+{
+ // The selection state is only saved persistently when "OK" is
+ // pressed. We need to manually restore the current selection
+ // when the widget is refreshed.
+ std::set<int> indices = get();
+ m_monitors.clear();
+
+ // FLTK recursively deletes all children for us.
+ clear();
+ begin();
+ layout();
+ end();
+
+ // Restore the current selection state.
+ set(indices);
+ redraw();
+}
+
bool MonitorArrangement::is_required(int m)
{
// A selected monitor is never required.
@@ -419,6 +446,24 @@ int MonitorArrangement::get_monitor_name(int m, char name[], size_t name_len)
#endif
}
+int MonitorArrangement::fltk_event_handler(int event)
+{
+ MonitorArrangement *self;
+ std::set<MonitorArrangement *>::iterator it;
+
+ for (it = instances.begin(); it != instances.end(); it++) {
+ self = *it;
+
+ switch (event) {
+ case FL_SCREEN_CONFIGURATION_CHANGED:
+ self->refresh();
+ break;
+ }
+ }
+
+ return 0;
+}
+
void MonitorArrangement::monitor_pressed(Fl_Widget *widget, void *user_data)
{
MonitorArrangement *self = (MonitorArrangement *) user_data;
diff --git a/vncviewer/MonitorArrangement.h b/vncviewer/MonitorArrangement.h
index ca1c4896..f1ba108d 100644
--- a/vncviewer/MonitorArrangement.h
+++ b/vncviewer/MonitorArrangement.h
@@ -46,6 +46,9 @@ private:
// Layout the monitor arrangement.
void layout();
+ // Refresh the monitor arrangement.
+ void refresh();
+
// Return true if the given monitor is required to be part of the configuration
// for it to be valid. A configuration is only valid if the framebuffer created
// from is rectangular.
@@ -68,6 +71,7 @@ private:
std::string description(int m);
int get_monitor_name(int m, char name[], size_t name_len);
+ static int fltk_event_handler(int event);
static void monitor_pressed(Fl_Widget *widget, void *user_data);
static void checkered_pattern_draw(
int x, int y, int width, int height, Fl_Color color);