From: Pierre Ossman Date: Mon, 6 Sep 2021 08:15:36 +0000 (+0200) Subject: Clean up global event handler structure X-Git-Tag: v1.11.90~6 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=dc6b4ef9dc895e983345ab73d6693a11437103f4;p=tigervnc.git Clean up global event handler structure Let's separate the standard global event handling from the hacky workarounds, for clarity. --- 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 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::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();