aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2021-09-06 10:15:36 +0200
committerPierre Ossman <ossman@cendio.se>2021-09-06 10:15:36 +0200
commitdc6b4ef9dc895e983345ab73d6693a11437103f4 (patch)
treeb14703a8e8e0651d1508d96480c56f43f2535a23
parentaadd42a9b499e2c8a082c6fb8be914b2982e2681 (diff)
downloadtigervnc-dc6b4ef9dc895e983345ab73d6693a11437103f4.tar.gz
tigervnc-dc6b4ef9dc895e983345ab73d6693a11437103f4.zip
Clean up global event handler structure
Let's separate the standard global event handling from the hacky workarounds, for clarity.
-rw-r--r--vncviewer/DesktopWindow.cxx83
-rw-r--r--vncviewer/DesktopWindow.h3
2 files changed, 49 insertions, 37 deletions
diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx
index d2a0d4c1..a8382fbf 100644
--- a/vncviewer/DesktopWindow.cxx
+++ b/vncviewer/DesktopWindow.cxx
@@ -73,7 +73,7 @@ static rfb::LogWriter vlog("DesktopWindow");
// Global due to http://www.fltk.org/str.php?L2177 and the similar
// issue for Fl::event_dispatch.
-static DesktopWindow *staticSelf = NULL;
+static std::set<DesktopWindow *> instances;
DesktopWindow::DesktopWindow(int w, int h, const char *name,
const rfb::PixelFormat& serverPF,
@@ -109,10 +109,13 @@ DesktopWindow::DesktopWindow(int w, int h, const char *name,
OptionsDialog::addCallback(handleOptions, this);
- staticSelf = this;
+ // Some events need to be caught globally
+ if (instances.size() == 0)
+ Fl::add_handler(fltkHandle);
+ instances.insert(this);
// Hack. See below...
- Fl::event_dispatch(&fltkHandle);
+ Fl::event_dispatch(fltkDispatch);
// Support for -geometry option. Note that although we do support
// negative coordinates, we do not support -XOFF-YOFF (ie
@@ -233,7 +236,10 @@ DesktopWindow::~DesktopWindow()
delete statsGraph;
- staticSelf = NULL;
+ instances.erase(this);
+
+ if (instances.size() == 0)
+ Fl::remove_handler(fltkHandle);
Fl::event_dispatch(Fl::handle_);
@@ -838,16 +844,7 @@ int DesktopWindow::handle(int event)
}
-void DesktopWindow::reconfigureFullscreen(void *data)
-{
- DesktopWindow *self = (DesktopWindow *)data;
-
- assert(self);
- self->fullscreen_on();
-}
-
-
-int DesktopWindow::fltkHandle(int event, Fl_Window *win)
+int DesktopWindow::fltkDispatch(int event, Fl_Window *win)
{
int ret;
@@ -859,28 +856,6 @@ int DesktopWindow::fltkHandle(int event, Fl_Window *win)
ret = Fl::handle_(event, win);
- switch (event) {
- case FL_SCREEN_CONFIGURATION_CHANGED:
- // Screens removed or added. Recreate fullscreen window if
- // necessary. On Windows, adding a second screen only works
- // reliable if we are using a timer. Otherwise, the window will
- // not be resized to cover the new screen. A timer makes sense
- // also on other systems, to make sure that whatever desktop
- // environment has a chance to deal with things before we do.
- // Please note that when using FullscreenSystemKeys on macOS, the
- // display configuration cannot be changed: macOS will not detect
- // added or removed screens and there will be no
- // FL_SCREEN_CONFIGURATION_CHANGED event. This is by design:
- // "When you capture a display, you have exclusive use of the
- // display. Other applications and system services are not allowed
- // to use the display or change its configuration. In addition,
- // they are not notified of display changes"
- if (staticSelf->fullscreen_active()) {
- Fl::remove_timeout(reconfigureFullscreen, staticSelf);
- Fl::add_timeout(0.5, reconfigureFullscreen, staticSelf);
- }
- }
-
// This is hackish and the result of the dodgy focus handling in FLTK.
// The basic problem is that FLTK's view of focus and the system's tend
// to differ, and as a result we do not see all the FL_FOCUS events we
@@ -921,6 +896,31 @@ int DesktopWindow::fltkHandle(int event, Fl_Window *win)
return ret;
}
+int DesktopWindow::fltkHandle(int event)
+{
+ switch (event) {
+ case FL_SCREEN_CONFIGURATION_CHANGED:
+ // Screens removed or added. Recreate fullscreen window if
+ // necessary. On Windows, adding a second screen only works
+ // reliable if we are using a timer. Otherwise, the window will
+ // not be resized to cover the new screen. A timer makes sense
+ // also on other systems, to make sure that whatever desktop
+ // environment has a chance to deal with things before we do.
+ // Please note that when using FullscreenSystemKeys on macOS, the
+ // display configuration cannot be changed: macOS will not detect
+ // added or removed screens and there will be no
+ // FL_SCREEN_CONFIGURATION_CHANGED event. This is by design:
+ // "When you capture a display, you have exclusive use of the
+ // display. Other applications and system services are not allowed
+ // to use the display or change its configuration. In addition,
+ // they are not notified of display changes"
+ Fl::remove_timeout(reconfigureFullscreen);
+ Fl::add_timeout(0.5, reconfigureFullscreen);
+ }
+
+ return 0;
+}
+
void DesktopWindow::fullscreen_on()
{
bool allMonitors = !strcasecmp(fullScreenMode, "all");
@@ -1222,6 +1222,17 @@ void DesktopWindow::handleResizeTimeout(void *data)
}
+void DesktopWindow::reconfigureFullscreen(void *data)
+{
+ std::set<DesktopWindow *>::iterator iter;
+
+ for (iter = instances.begin(); iter != instances.end(); ++iter) {
+ if ((*iter)->fullscreen_active())
+ (*iter)->fullscreen_on();
+ }
+}
+
+
void DesktopWindow::remoteResize(int width, int height)
{
ScreenSet layout;
diff --git a/vncviewer/DesktopWindow.h b/vncviewer/DesktopWindow.h
index 2f23d781..f25985cc 100644
--- a/vncviewer/DesktopWindow.h
+++ b/vncviewer/DesktopWindow.h
@@ -92,7 +92,8 @@ private:
void setOverlay(const char *text, ...) __printf_attr(2, 3);
static void updateOverlay(void *data);
- static int fltkHandle(int event, Fl_Window *win);
+ static int fltkDispatch(int event, Fl_Window *win);
+ static int fltkHandle(int event);
void grabKeyboard();
void ungrabKeyboard();