From 8213ba94aa2b1a83f7da8b603935811c05c7def5 Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Sun, 16 Jan 2022 18:49:26 +0100 Subject: Improve Fl_GTK_Native_File_Chooser_Driver in relation to FLTK windows. Implement a new way to make the GTK file-chooser window modal-like by preventing any event processing by other FLTK windows. The new way is also no longer X11-specific. --- src/Fl_Native_File_Chooser_GTK.cxx | 50 ++++++++++++++++++++++++++---- src/Fl_Screen_Driver.H | 3 +- src/drivers/Posix/Fl_Posix_System_Driver.H | 3 +- src/drivers/X11/Fl_X11_Screen_Driver.H | 5 +-- src/drivers/X11/Fl_X11_Screen_Driver.cxx | 42 +------------------------ src/drivers/X11/Fl_X11_System_Driver.H | 3 +- src/drivers/X11/Fl_X11_System_Driver.cxx | 16 +--------- 7 files changed, 50 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/Fl_Native_File_Chooser_GTK.cxx b/src/Fl_Native_File_Chooser_GTK.cxx index 976d6f993..bfb3dbe9d 100644 --- a/src/Fl_Native_File_Chooser_GTK.cxx +++ b/src/Fl_Native_File_Chooser_GTK.cxx @@ -1,7 +1,7 @@ // // FLTK native file chooser widget wrapper for GTK's GtkFileChooserDialog // -// Copyright 1998-2021 by Bill Spitzak and others. +// Copyright 1998-2022 by Bill Spitzak and others. // Copyright 2012 IMM // // This library is free software. Distribution and use rights are outlined in @@ -29,6 +29,7 @@ #include #include // for dlopen et al #include "drivers/X11/Fl_X11_System_Driver.H" +#include "Fl_Window_Driver.H" #include "Fl_Screen_Driver.H" /* --------------------- Type definitions from GLIB and GTK --------------------- */ @@ -624,6 +625,11 @@ static void minus_cb(GtkWidget *togglebutton, GtkImage *preview) { } +static int fnfc_dispatch(int /*event*/, Fl_Window* /*win*/) { + return 0; +} + + int Fl_GTK_Native_File_Chooser_Driver::fl_gtk_chooser_wrapper() { int result = 1; @@ -759,19 +765,42 @@ int Fl_GTK_Native_File_Chooser_Driver::fl_gtk_chooser_wrapper() } fl_gtk_file_chooser_set_extra_widget((GtkFileChooser *)gtkw_ptr, extra); fl_gtk_widget_show_all(extra); - Fl_Window* firstw = Fl::first_window(); fl_gtk_widget_show_now(gtkw_ptr); // map the GTK window on screen - if (firstw) { - Fl::screen_driver()->make_transient(Fl_Posix_System_Driver::ptr_gtk, gtkw_ptr, firstw); - } gboolean state = fl_gtk_file_chooser_get_show_hidden((GtkFileChooser *)gtkw_ptr); fl_gtk_toggle_button_set_active((GtkToggleButton *)show_hidden_button, state); + + Fl_Event_Dispatch old_dispatch = Fl::event_dispatch(); + // prevent FLTK from processing any event + Fl::event_dispatch(fnfc_dispatch); + struct win_dims { + Fl_Window *win; + int minw,minh,maxw,maxh; + struct win_dims *next; + } *first_dim = NULL; + // consider all bordered, top-level FLTK windows + Fl_Window *win = Fl::first_window(); + while (win) { + if (win->border()) { + Fl_Window_Driver *dr = Fl_Window_Driver::driver(win); + win_dims *dim = new win_dims; + dim->win = win; + dim->minw = dr->minw(); + dim->minh = dr->minh(); + dim->maxw = dr->maxw(); + dim->maxh = dr->maxh(); + //make win un-resizable + win->size_range(win->w(), win->h(), win->w(), win->h()); + dim->next = first_dim; + first_dim = dim; + } + win = Fl::next_window(win); + } gint response_id = GTK_RESPONSE_NONE; fl_g_signal_connect_data(gtkw_ptr, "response", G_CALLBACK(run_response_handler), &response_id, NULL, (GConnectFlags) 0); while (response_id == GTK_RESPONSE_NONE) { // loop that shows the GTK dialog window fl_gtk_main_iteration(); // one iteration of the GTK event loop - ((Fl_Posix_System_Driver*)Fl::system_driver())->emulate_modal_dialog(); + while (Fl::ready()) Fl::check(); // queued iterations of the FLTK event loop } if (response_id == GTK_RESPONSE_ACCEPT) { @@ -829,6 +858,15 @@ int Fl_GTK_Native_File_Chooser_Driver::fl_gtk_chooser_wrapper() // the GtkFileChooserDialog is removed from the display correctly while (fl_gtk_events_pending ()) fl_gtk_main_iteration (); + Fl::event_dispatch(old_dispatch); + while (first_dim) { + win_dims *dim = first_dim; + //give back win its resizing parameters + dim->win->size_range(dim->minw, dim->minh, dim->maxw, dim->maxh); + first_dim = dim->next; + delete dim; + } + return result; } // fl_gtk_chooser_wrapper diff --git a/src/Fl_Screen_Driver.H b/src/Fl_Screen_Driver.H index e33950b8a..027b30077 100644 --- a/src/Fl_Screen_Driver.H +++ b/src/Fl_Screen_Driver.H @@ -1,7 +1,7 @@ // // All screen related calls in a driver style class. // -// Copyright 1998-2021 by Bill Spitzak and others. +// Copyright 1998-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -206,7 +206,6 @@ public: virtual APP_SCALING_CAPABILITY rescalable() { return NO_APP_SCALING; } // supports Fl_Window::default_icons() virtual void default_icons(const Fl_RGB_Image *icons[], int count); - virtual void make_transient(void *, void *, Fl_Window *) {} }; #endif // !FL_SCREEN_DRIVER_H diff --git a/src/drivers/Posix/Fl_Posix_System_Driver.H b/src/drivers/Posix/Fl_Posix_System_Driver.H index 9d2c0fa23..752b54201 100644 --- a/src/drivers/Posix/Fl_Posix_System_Driver.H +++ b/src/drivers/Posix/Fl_Posix_System_Driver.H @@ -2,7 +2,7 @@ // Definition of POSIX system driver // for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2021 by Bill Spitzak and others. +// Copyright 2010-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -88,7 +88,6 @@ public: virtual void lock_ring(); virtual void unlock_ring(); #endif - virtual void emulate_modal_dialog() {} }; #endif // FL_POSIX_SYSTEM_DRIVER_H diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.H b/src/drivers/X11/Fl_X11_Screen_Driver.H index 8a82486fa..7d665dbb4 100644 --- a/src/drivers/X11/Fl_X11_Screen_Driver.H +++ b/src/drivers/X11/Fl_X11_Screen_Driver.H @@ -2,7 +2,7 @@ // Definition of X11 Screen interface // for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2018 by Bill Spitzak and others. +// Copyright 2010-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -103,9 +103,6 @@ public: // --- compute dimensions of an Fl_Offscreen virtual void offscreen_size(Fl_Offscreen o, int &width, int &height); virtual void default_icons(const Fl_RGB_Image *icons[], int count); -#if HAVE_DLSYM && HAVE_DLFCN_H - virtual void make_transient(void *ptr_gtk, void *gtk_window, Fl_Window *win); -#endif }; diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.cxx b/src/drivers/X11/Fl_X11_Screen_Driver.cxx index 717132d1c..beb30df83 100644 --- a/src/drivers/X11/Fl_X11_Screen_Driver.cxx +++ b/src/drivers/X11/Fl_X11_Screen_Driver.cxx @@ -1,7 +1,7 @@ // // Definition of X11 Screen interface // -// Copyright 1998-2020 by Bill Spitzak and others. +// Copyright 1998-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -1399,43 +1399,3 @@ void Fl_X11_Screen_Driver::desktop_scale_factor() } #endif // USE_XFT - -#if HAVE_DLSYM && HAVE_DLFCN_H -void Fl_X11_Screen_Driver::make_transient(void *ptr_gtk, void *gtkw_window, Fl_Window *win) { - typedef int gboolean; - typedef struct _GdkDrawable GdkWindow; - typedef struct _GtkWidget GtkWidget; - - typedef unsigned long (*XX_gdk_x11_window_get_type)(); - static XX_gdk_x11_window_get_type fl_gdk_x11_window_get_type = NULL; - - typedef gboolean (*XX_g_type_check_instance_is_a)(void *type_instance, unsigned long iface_type); - static XX_g_type_check_instance_is_a fl_g_type_check_instance_is_a = NULL; - - typedef Window (*gdk_to_X11_t)(GdkWindow*); - static gdk_to_X11_t fl_gdk_to_X11 = NULL; - - typedef GdkWindow* (*XX_gtk_widget_get_window)(GtkWidget *); - static XX_gtk_widget_get_window fl_gtk_widget_get_window = NULL; - - if (!fl_gdk_to_X11) { - fl_gdk_to_X11 = (gdk_to_X11_t)dlsym(ptr_gtk, "gdk_x11_drawable_get_xid"); - if (!fl_gdk_to_X11) fl_gdk_to_X11 = (gdk_to_X11_t)dlsym(ptr_gtk, "gdk_x11_window_get_xid"); - if (!fl_gdk_to_X11) return; - fl_gdk_x11_window_get_type = (XX_gdk_x11_window_get_type)dlsym(ptr_gtk, "gdk_x11_window_get_type"); - fl_g_type_check_instance_is_a = (XX_g_type_check_instance_is_a)dlsym(ptr_gtk, "g_type_check_instance_is_a"); - fl_gtk_widget_get_window = (XX_gtk_widget_get_window)dlsym(ptr_gtk, "gtk_widget_get_window"); - if (!fl_gtk_widget_get_window) return; - } - GdkWindow* gdkw = fl_gtk_widget_get_window((GtkWidget*)gtkw_window); - - // Make sure the Dialog is an X11 window because it's not on Wayland. - // Until we find how to make a wayland window transient for an X11 window, - // we make the GTK window transient only when it's X11-based. - if ( (!fl_gdk_x11_window_get_type) || (!fl_g_type_check_instance_is_a) || - fl_g_type_check_instance_is_a(gdkw, fl_gdk_x11_window_get_type()) ) { - Window xw = fl_gdk_to_X11(gdkw); // get the X11 ref of the GTK window - if (xw) XSetTransientForHint(fl_display, xw, fl_xid(win)); // set the GTK window transient for the last FLTK win - } -} -#endif //HAVE_DLSYM && HAVE_DLFCN_H diff --git a/src/drivers/X11/Fl_X11_System_Driver.H b/src/drivers/X11/Fl_X11_System_Driver.H index 69649bc36..146a48e83 100644 --- a/src/drivers/X11/Fl_X11_System_Driver.H +++ b/src/drivers/X11/Fl_X11_System_Driver.H @@ -2,7 +2,7 @@ // Definition of Posix system driver // for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2018 by Bill Spitzak and others. +// Copyright 2010-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -64,7 +64,6 @@ public: virtual void add_fd(int fd, Fl_FD_Handler cb, void* = 0); virtual void remove_fd(int, int when); virtual void remove_fd(int); - virtual void emulate_modal_dialog(); }; #endif /* FL_X11_SYSTEM_DRIVER_H */ diff --git a/src/drivers/X11/Fl_X11_System_Driver.cxx b/src/drivers/X11/Fl_X11_System_Driver.cxx index 30dfe8bcf..7868ae3a1 100644 --- a/src/drivers/X11/Fl_X11_System_Driver.cxx +++ b/src/drivers/X11/Fl_X11_System_Driver.cxx @@ -2,7 +2,7 @@ // Definition of Posix system driver // for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2020 by Bill Spitzak and others. +// Copyright 2010-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -618,18 +618,4 @@ void Fl_X11_System_Driver::own_colormap() { #endif // USE_COLORMAP } - -void Fl_X11_System_Driver::emulate_modal_dialog() { - while (XEventsQueued(fl_display, QueuedAfterReading)) { // emulate modal dialog - XEvent xevent; - XNextEvent(fl_display, &xevent); - Window xid = xevent.xany.window; - if (xevent.type == ConfigureNotify) xid = xevent.xmaprequest.window; - if (!fl_find(xid)) continue; // skip events to non-FLTK windows - // process Expose and ConfigureNotify events - if ( xevent.type == Expose || xevent.type == ConfigureNotify ) fl_handle(xevent); - } - Fl::flush(); // do the drawings needed after Expose events -} - #endif // !defined(FL_DOXYGEN) -- cgit v1.2.3