diff options
| -rw-r--r-- | src/Fl_Native_File_Chooser_GTK.cxx | 45 | ||||
| -rw-r--r-- | src/drivers/Posix/Fl_Posix_System_Driver.H | 2 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_System_Driver.H | 2 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_System_Driver.cxx | 54 |
4 files changed, 61 insertions, 42 deletions
diff --git a/src/Fl_Native_File_Chooser_GTK.cxx b/src/Fl_Native_File_Chooser_GTK.cxx index e9decde1e..afee784f1 100644 --- a/src/Fl_Native_File_Chooser_GTK.cxx +++ b/src/Fl_Native_File_Chooser_GTK.cxx @@ -52,7 +52,6 @@ typedef struct _GtkWidget GtkWidget; typedef struct _GtkFileChooser GtkFileChooser; typedef struct _GtkDialog GtkDialog; typedef struct _GtkWindow GtkWindow; -typedef struct _GdkDrawable GdkWindow; typedef struct _GtkFileFilter GtkFileFilter; typedef struct _GtkToggleButton GtkToggleButton; typedef struct _GdkPixbuf GdkPixbuf; @@ -260,22 +259,6 @@ static XX_gtk_file_chooser_set_extra_widget fl_gtk_file_chooser_set_extra_widget typedef void (*XX_gtk_widget_show_now)(GtkWidget *); static XX_gtk_widget_show_now fl_gtk_widget_show_now = NULL; -// GdkWindow* gtk_widget_get_window(GtkWidget *); -typedef GdkWindow* (*XX_gtk_widget_get_window)(GtkWidget *); -static XX_gtk_widget_get_window fl_gtk_widget_get_window = NULL; - -// Window gdk_x11_drawable_get_xid(GdkWindow *); or gdk_x11_window_get_xid -typedef Window (*gdk_to_X11_t)(GdkWindow*); -static gdk_to_X11_t fl_gdk_to_X11 = NULL; - -// unsigned long gdk_x11_window_get_type(); -typedef unsigned long (*XX_gdk_x11_window_get_type)(); -static XX_gdk_x11_window_get_type fl_gdk_x11_window_get_type = NULL; - -//gboolean g_type_check_instance_is_a(void *type_instance, unsigned long iface_type) -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; - // GtkWidget *gtk_check_button_new_with_label(const gchar *); typedef GtkWidget* (*XX_gtk_check_button_new_with_label)(const gchar *); static XX_gtk_check_button_new_with_label fl_gtk_check_button_new_with_label = NULL; @@ -774,16 +757,8 @@ int Fl_GTK_Native_File_Chooser_Driver::fl_gtk_chooser_wrapper() 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_gdk_to_X11) { - GdkWindow* gdkw = fl_gtk_widget_get_window(gtkw_ptr); - // 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(firstw)); // set the GTK window transient for the last FLTK win - } + if (firstw) { + ((Fl_Posix_System_Driver*)Fl::system_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); @@ -792,16 +767,7 @@ int Fl_GTK_Native_File_Chooser_Driver::fl_gtk_chooser_wrapper() 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 - 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 + ((Fl_Posix_System_Driver*)Fl::system_driver())->emulate_modal_dialog(); } if (response_id == GTK_RESPONSE_ACCEPT) { @@ -914,7 +880,6 @@ void Fl_GTK_Native_File_Chooser_Driver::probe_for_GTK_libs(void) { GET_SYM(gtk_file_filter_get_name, ptr_gtk); GET_SYM(gtk_file_chooser_set_extra_widget, ptr_gtk); GET_SYM(gtk_widget_show_now, ptr_gtk); - GET_SYM(gtk_widget_get_window, ptr_gtk); GET_SYM(gtk_file_chooser_set_preview_widget_active, ptr_gtk); GET_SYM(gtk_file_chooser_set_preview_widget, ptr_gtk); GET_SYM(gtk_file_chooser_get_preview_widget, ptr_gtk); @@ -929,10 +894,6 @@ void Fl_GTK_Native_File_Chooser_Driver::probe_for_GTK_libs(void) { GET_SYM(gtk_widget_show_all, ptr_gtk); GET_SYM(gtk_table_attach_defaults, ptr_gtk); GET_SYM(g_object_unref, ptr_gtk); - 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"); - 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"); GET_SYM(gtk_check_button_new_with_label, ptr_gtk); GET_SYM(g_signal_connect_data, ptr_gtk); GET_SYM(gtk_toggle_button_get_active, ptr_gtk); diff --git a/src/drivers/Posix/Fl_Posix_System_Driver.H b/src/drivers/Posix/Fl_Posix_System_Driver.H index 2c577c310..80faabaff 100644 --- a/src/drivers/Posix/Fl_Posix_System_Driver.H +++ b/src/drivers/Posix/Fl_Posix_System_Driver.H @@ -88,6 +88,8 @@ public: virtual void lock_ring(); virtual void unlock_ring(); #endif + virtual void make_transient(void *ptr_gtk, void *gtk_window, Fl_Window *win) {} + virtual void emulate_modal_dialog() {} }; #endif // FL_POSIX_SYSTEM_DRIVER_H diff --git a/src/drivers/X11/Fl_X11_System_Driver.H b/src/drivers/X11/Fl_X11_System_Driver.H index 1ef17bb8b..f95fb6b41 100644 --- a/src/drivers/X11/Fl_X11_System_Driver.H +++ b/src/drivers/X11/Fl_X11_System_Driver.H @@ -64,6 +64,8 @@ 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 make_transient(void *ptr_gtk, void *gtk_window, Fl_Window *win); + 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 8beed262b..100a72e2f 100644 --- a/src/drivers/X11/Fl_X11_System_Driver.cxx +++ b/src/drivers/X11/Fl_X11_System_Driver.cxx @@ -618,4 +618,58 @@ void Fl_X11_System_Driver::own_colormap() { #endif // USE_COLORMAP } + +void Fl_X11_System_Driver::make_transient(void *ptr_gtk, void *gtkw_window, Fl_Window *win) { +#if HAVE_DLSYM && HAVE_DLFCN_H + 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 +} + +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) |
