Wayland: call gtk_surface1_set_modal() of GTK Shell protocol for modal wins

This has the Mutter compositor open modal windows at the center of their parent window
rather than at an unpredictable display position before this commit.
This commit is contained in:
ManoloFLTK 2024-05-11 19:52:00 +02:00
parent e9feef99fa
commit ef33f3e0e2
4 changed files with 15 additions and 13 deletions

View File

@ -920,7 +920,7 @@ setting, FLTK implements part of the
<a href=https://wayland.app/protocols/gtk-shell>GTK Shell</a> protocol as follows.
Mutter, gnome's Wayland compositor, declares its support of the <tt>GTK Shell</tt>
protocol calling \c registry_handle_global() with its \c interface argument equal to
\c "gtk_shell1". FLTK initializes then a static global variable \c gtk_shell of type
\c "gtk_shell1". FLTK initializes then member variable \c seat->gtk_shell of type
<tt>struct gtk_shell1*</tt>.
Member functions of \c pointer_listener mentioned above run for all mouse events
@ -939,7 +939,7 @@ when the mouse leaves this titlebar. When there's a click on a titlebar,
member function \c pointer_button() runs this code
\code
if (gtk_shell_surface && state == WL_POINTER_BUTTON_STATE_PRESSED && button == BTN_MIDDLE) {
struct gtk_surface1 *gtk_surface = gtk_shell1_get_gtk_surface(gtk_shell, gtk_shell_surface);
struct gtk_surface1 *gtk_surface = gtk_shell1_get_gtk_surface(seat->gtk_shell, gtk_shell_surface);
gtk_surface1_titlebar_gesture(gtk_surface, serial, seat->wl_seat, GTK_SURFACE1_GESTURE_MIDDLE_CLICK);
gtk_surface1_release(gtk_surface);
return;

View File

@ -63,6 +63,7 @@ public:
struct xkb_compose_state *xkb_compose_state;
char *name;
struct zwp_text_input_v3 *text_input;
struct gtk_shell1 *gtk_shell;
};
struct output { // one record for each screen
uint32_t id;

View File

@ -91,7 +91,6 @@ struct pointer_output {
static Fl_Int_Vector key_vector; // used by Fl_Wayland_Screen_Driver::event_key()
static struct gtk_shell1 *gtk_shell = NULL;
static struct wl_surface *gtk_shell_surface = NULL;
Fl_Wayland_Screen_Driver::compositor_name Fl_Wayland_Screen_Driver::compositor =
@ -204,10 +203,11 @@ static Fl_Window *event_coords_from_surface(struct wl_surface *surface,
static void pointer_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial,
struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) {
struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data;
Fl_Window *win = event_coords_from_surface(surface, surface_x, surface_y);
if (!win && gtk_shell) { // check whether surface is the headerbar of a GTK-decorated window
static bool using_GTK = true;
if (!win && seat->gtk_shell && using_GTK) { // check whether surface is the headerbar of a GTK-decorated window
Fl_X *xp = Fl_X::first;
bool using_GTK = true;
while (xp && using_GTK) { // all mapped windows
struct wld_window *xid = (struct wld_window*)xp->xid;
if (xid->kind == Fl_Wayland_Window_Driver::DECORATED &&
@ -217,17 +217,11 @@ static void pointer_enter(void *data, struct wl_pointer *wl_pointer, uint32_t se
}
xp = xp->next;
}
if (!using_GTK) {
gtk_shell1_destroy(gtk_shell);
gtk_shell = NULL;
}
}
if (!win) return;
// use custom cursor if present
struct wl_cursor *cursor =
fl_wl_xid(win)->custom_cursor ? fl_wl_xid(win)->custom_cursor->wl_cursor : NULL;
struct Fl_Wayland_Screen_Driver::seat *seat =
(struct Fl_Wayland_Screen_Driver::seat*)data;
Fl_Wayland_Screen_Driver::do_set_cursor(seat, cursor);
seat->serial = serial;
seat->pointer_enter_serial = serial;
@ -289,7 +283,7 @@ static void pointer_button(void *data,
(struct Fl_Wayland_Screen_Driver::seat*)data;
if (gtk_shell_surface && state == WL_POINTER_BUTTON_STATE_PRESSED &&
button == BTN_MIDDLE) {
struct gtk_surface1 *gtk_surface = gtk_shell1_get_gtk_surface(gtk_shell,
struct gtk_surface1 *gtk_surface = gtk_shell1_get_gtk_surface(seat->gtk_shell,
gtk_shell_surface);
gtk_surface1_titlebar_gesture(gtk_surface, serial, seat->wl_seat,
GTK_SURFACE1_GESTURE_MIDDLE_CLICK);
@ -1264,7 +1258,7 @@ static void registry_handle_global(void *user_data, struct wl_registry *wl_regis
Fl_Wayland_Screen_Driver::compositor = Fl_Wayland_Screen_Driver::MUTTER;
//fprintf(stderr, "Running the Mutter compositor\n");
if ( version >= 5) {
gtk_shell = (struct gtk_shell1*)wl_registry_bind(wl_registry, id,
scr_driver->seat->gtk_shell = (struct gtk_shell1*)wl_registry_bind(wl_registry, id,
&gtk_shell1_interface, 5);
}
} else if (strcmp(interface, "weston_desktop_shell") == 0) {

View File

@ -22,6 +22,7 @@
#include <wayland-cursor.h>
#include "../../../libdecor/build/fl_libdecor.h"
#include "xdg-shell-client-protocol.h"
#include "gtk-shell-client-protocol.h"
#include <pango/pangocairo.h>
#include <FL/Fl_Overlay_Window.H>
#include <FL/Fl_Tooltip.H>
@ -1514,6 +1515,12 @@ void Fl_Wayland_Window_Driver::makeWindow()
if (top_dr->xdg_toplevel()) xdg_toplevel_set_parent(new_window->xdg_toplevel,
top_dr->xdg_toplevel());
}
if (scr_driver->seat->gtk_shell && pWindow->modal()) {
struct gtk_surface1 *gtk_surface = gtk_shell1_get_gtk_surface(scr_driver->seat->gtk_shell,
new_window->wl_surface);
gtk_surface1_set_modal(gtk_surface);
gtk_surface1_release(gtk_surface);
}
}
size_range();