summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2021-03-31 18:58:21 +0200
committerManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2021-03-31 18:58:34 +0200
commit30725faf0acf5ac308a09bc37512bed47804d2e4 (patch)
tree7e3b791cf9212d87b44b21add502d6432d08e337 /src/drivers
parent2a6e9d9493c37de1972953afe9dfb88a2352bab9 (diff)
Move the X11-specific part of GTK native file chooser to Fl_X11_System_Driver
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/Posix/Fl_Posix_System_Driver.H2
-rw-r--r--src/drivers/X11/Fl_X11_System_Driver.H2
-rw-r--r--src/drivers/X11/Fl_X11_System_Driver.cxx54
3 files changed, 58 insertions, 0 deletions
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)