diff options
| -rw-r--r-- | libdecor/build/fl_libdecor-plugins.c | 238 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 10 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx | 18 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx | 2 |
4 files changed, 20 insertions, 248 deletions
diff --git a/libdecor/build/fl_libdecor-plugins.c b/libdecor/build/fl_libdecor-plugins.c index 35565a9e1..1d961dd3d 100644 --- a/libdecor/build/fl_libdecor-plugins.c +++ b/libdecor/build/fl_libdecor-plugins.c @@ -31,15 +31,10 @@ # define HAVE_GTK 0 #endif -#if HAVE_GTK -# include "gtk-shell-client-protocol.h" -#endif - #if USE_SYSTEM_LIBDECOR #include "../src/libdecor-plugin.h" #if HAVE_GTK #include <linux/input.h> -#include "gtk-shell-protocol.c" #endif enum zxdg_toplevel_decoration_v1_mode { @@ -237,55 +232,6 @@ struct libdecor_frame_gtk { struct wl_list link; }; -#if USE_SYSTEM_LIBDECOR -struct libdecor_plugin_gtk { - struct libdecor_plugin plugin; - struct wl_callback *globals_callback; - struct wl_callback *globals_callback_shm; - struct libdecor *context; - struct wl_registry *wl_registry; - struct wl_subcompositor *wl_subcompositor; - struct wl_compositor *wl_compositor; - struct wl_shm *wl_shm; - struct wl_callback *shm_callback; - bool has_argb; - struct wl_list visible_frame_list; - struct wl_list seat_list; - struct wl_list output_list; - char *cursor_theme_name; - int cursor_size; - int double_click_time_ms; -}; - -struct seat { - struct libdecor_plugin_gtk *plugin_gtk; - char *name; - struct wl_seat *wl_seat; - struct wl_pointer *wl_pointer; - struct wl_touch *wl_touch; - struct wl_surface *cursor_surface; - struct wl_cursor *current_cursor; - int cursor_scale; - struct wl_list cursor_outputs; - struct wl_cursor_theme *cursor_theme; - struct wl_cursor *cursors[8]; // 8 replaces ARRAY_LENGTH(cursor_names) - struct wl_cursor *cursor_left_ptr; - struct wl_surface *pointer_focus; - struct wl_surface *touch_focus; - int pointer_x, pointer_y; - uint32_t pointer_button_time_stamp; - uint32_t touch_down_time_stamp; - uint32_t serial; - bool grabbed; - struct wl_list link; -}; - -static bool own_surface(struct wl_surface *surface) -{ - return true; -} -#endif // USE_SYSTEM_LIBDECOR - #endif // USE_SYSTEM_LIBDECOR || !HAVE_GTK @@ -391,187 +337,3 @@ unsigned char *fl_libdecor_titlebar_buffer(struct libdecor_frame *frame, } return NULL; } - - -/* === Beginning of code to add support of GTK Shell to libdecor-gtk === */ -#if HAVE_GTK - -static struct gtk_shell1 *gtk_shell = NULL; -static uint32_t doubleclick_time = 250; - -// libdecor's button member of wl_pointer_listener objects -static void (*decor_pointer_button)(void*, struct wl_pointer *, - uint32_t , - uint32_t , - uint32_t , - uint32_t); - -// FLTK's replacement for button member of wl_pointer_listener objects -static void fltk_pointer_button(void *data, - struct wl_pointer *wl_pointer, - uint32_t serial, - uint32_t time, - uint32_t button, - uint32_t state) { - struct seat *seat = data; - struct libdecor_frame_gtk *frame_gtk; - if (!seat->pointer_focus || !own_surface(seat->pointer_focus)) - return; - - frame_gtk = wl_surface_get_user_data(seat->pointer_focus); - if (!frame_gtk) - return; - - if (button == BTN_MIDDLE && state == WL_POINTER_BUTTON_STATE_PRESSED) { - struct gtk_surface1 *gtk_surface = gtk_shell1_get_gtk_surface(gtk_shell, - frame_gtk->headerbar.wl_surface); - gtk_surface1_titlebar_gesture(gtk_surface, serial, - seat->wl_seat, GTK_SURFACE1_GESTURE_MIDDLE_CLICK); - gtk_surface1_release(gtk_surface); - return; - } else if (button == BTN_RIGHT && state == WL_POINTER_BUTTON_STATE_PRESSED) { - struct gtk_surface1 *gtk_surface = gtk_shell1_get_gtk_surface(gtk_shell, - frame_gtk->headerbar.wl_surface); - gtk_surface1_titlebar_gesture(gtk_surface, serial, - seat->wl_seat, GTK_SURFACE1_GESTURE_RIGHT_CLICK); - gtk_surface1_release(gtk_surface); - return; - } else if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED) { - if (time - seat->pointer_button_time_stamp < doubleclick_time) { - seat->pointer_button_time_stamp = 0; - struct gtk_surface1 *gtk_surface = gtk_shell1_get_gtk_surface(gtk_shell, - frame_gtk->headerbar.wl_surface); - gtk_surface1_titlebar_gesture(gtk_surface, serial, - seat->wl_seat, GTK_SURFACE1_GESTURE_DOUBLE_CLICK); - gtk_surface1_release(gtk_surface); - return; - } - } - decor_pointer_button(data, wl_pointer, serial, time, button, state); -} - -#if USE_SYSTEM_LIBDECOR -static struct border_component_gtk * -get_component_for_surface(struct libdecor_frame_gtk *frame_gtk, - const struct wl_surface *surface) -{ - if (frame_gtk->shadow.wl_surface == surface) - return &frame_gtk->shadow; - if (frame_gtk->headerbar.wl_surface == surface) - return &frame_gtk->headerbar; - return NULL; -} -#endif - - -// libdecor's touch_down member of wl_touch_listener objects -void (*decor_touch_down)(void *data, struct wl_touch *wl_touch, uint32_t serial, - uint32_t time, struct wl_surface *surface, int32_t id, - wl_fixed_t x, wl_fixed_t y); - - -// FLTK's replacement for touch_down member of wl_touch_listener objects -static void fltk_touch_down(void *data, struct wl_touch *wl_touch, uint32_t serial, - uint32_t time, struct wl_surface *surface, int32_t id, wl_fixed_t x, wl_fixed_t y) -{ - struct seat *seat = data; - struct libdecor_frame_gtk *frame_gtk; - if (!surface || !own_surface(surface)) return; - frame_gtk = wl_surface_get_user_data(surface); - if (!frame_gtk) return; - seat->touch_focus = surface; - frame_gtk->touch_active = get_component_for_surface(frame_gtk, surface); - if (!frame_gtk->touch_active) return; - - if (frame_gtk->touch_active->type == HEADER && - frame_gtk->hdr_focus.type < HEADER_MIN && - time - seat->touch_down_time_stamp < - (uint32_t)frame_gtk->plugin_gtk->double_click_time_ms - ) { - struct gtk_surface1 *gtk_surface = gtk_shell1_get_gtk_surface( - gtk_shell, surface); - gtk_surface1_titlebar_gesture(gtk_surface, serial, seat->wl_seat, - GTK_SURFACE1_GESTURE_DOUBLE_CLICK); - gtk_surface1_release(gtk_surface); - } else { - decor_touch_down(data, wl_touch, serial, time, surface, id, x, y); - } -} - - -struct wl_object { // copied from wayland-private.h - const struct wl_interface *interface; - const void *implementation; - uint32_t id; -}; - -#endif // HAVE_GTK - - -// replace libdecor's pointer_button by FLTK's -void use_FLTK_pointer_button(struct libdecor_frame *frame) { -#if HAVE_GTK - static const char *my_plugin = NULL; - if (!my_plugin) my_plugin = get_libdecor_plugin_description(frame); - if (!my_plugin || strcmp(my_plugin, "GTK3 plugin")) return; - static struct wl_pointer_listener *fltk_listener = NULL; - if (!gtk_shell || fltk_listener) return; - struct libdecor_frame_gtk *lfg = (struct libdecor_frame_gtk *)frame; - if (wl_list_empty(&lfg->plugin_gtk->seat_list)) return; - struct seat *seat; - wl_list_for_each(seat, &lfg->plugin_gtk->seat_list, link) { - break; - } - - struct wl_surface *surface = lfg->headerbar.wl_surface; - if (surface && !own_surface(surface)) { - // occurs if libdecor-gtk.so was dynamically loaded via LIBDECOR_PLUGIN_DIR - gtk_shell = NULL; - return; - } - - struct wl_object *object = (struct wl_object *)seat->wl_pointer; - if (!object) return; - struct wl_pointer_listener *decor_listener = - (struct wl_pointer_listener*)object->implementation; - fltk_listener = - (struct wl_pointer_listener*)malloc(sizeof(struct wl_pointer_listener)); - // initialize FLTK's listener with libdecor's values - *fltk_listener = *decor_listener; - // memorize libdecor's button cb - decor_pointer_button = decor_listener->button; - // replace libdecor's button by FLTK's - fltk_listener->button = fltk_pointer_button; - // replace the pointer listener by a copy whose button member is FLTK's - object->implementation = fltk_listener; - - object = (struct wl_object *)seat->wl_touch; - if (object) { - struct wl_touch_listener *decor_touch_listener = - (struct wl_touch_listener*)object->implementation; - struct wl_touch_listener *fltk_touch_listener = - (struct wl_touch_listener*)malloc(sizeof(struct wl_touch_listener)); - // initialize FLTK's touch listener with libdecor's values - *fltk_touch_listener = *decor_touch_listener; - // memorize libdecor's down cb - decor_touch_down = decor_touch_listener->down; - // replace libdecor's down by FLTK's - fltk_touch_listener->down = fltk_touch_down; - // replace the touch listener by a copy whose down member is FLTK's - object->implementation = fltk_touch_listener; - } - - // get gnome's double_click_time_ms value - doubleclick_time = lfg->plugin_gtk->double_click_time_ms; -#endif // HAVE_GTK -} - - -void bind_to_gtk_shell(struct wl_registry *wl_registry, uint32_t id) { -#if HAVE_GTK - gtk_shell = (struct gtk_shell1*)wl_registry_bind(wl_registry, id, - >k_shell1_interface, 5); -#endif // HAVE_GTK -} - -/* === End of code to add support of GTK Shell to libdecor-gtk === */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fb90aec75..be2634d62 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -709,17 +709,15 @@ if (UNIX AND OPTION_USE_WAYLAND) list (APPEND STATIC_FILES "xdg-decoration-protocol.c") list (APPEND SHARED_FILES "xdg-decoration-protocol.c") endif (NOT OPTION_USE_SYSTEM_LIBDECOR) - if (GTK_FOUND AND (OPTION_USE_SYSTEM_LIBDECOR OR OPTION_ALLOW_GTK_PLUGIN)) - add_custom_command( + add_custom_command( OUTPUT gtk-shell-protocol.c gtk-shell-client-protocol.h COMMAND wayland-scanner private-code ${CMAKE_CURRENT_SOURCE_DIR}/../libdecor/build/gtk-shell.xml gtk-shell-protocol.c COMMAND wayland-scanner client-header ${CMAKE_CURRENT_SOURCE_DIR}/../libdecor/build/gtk-shell.xml gtk-shell-client-protocol.h DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../libdecor/build/gtk-shell.xml VERBATIM - ) - list (APPEND STATIC_FILES "gtk-shell-protocol.c") - list (APPEND SHARED_FILES "gtk-shell-protocol.c") - endif (GTK_FOUND AND (OPTION_USE_SYSTEM_LIBDECOR OR OPTION_ALLOW_GTK_PLUGIN)) + ) + list (APPEND STATIC_FILES "gtk-shell-protocol.c") + list (APPEND SHARED_FILES "gtk-shell-protocol.c") add_custom_command( OUTPUT text-input-protocol.c text-input-client-protocol.h COMMAND wayland-scanner private-code ${PROTOCOLS}/unstable/text-input/text-input-unstable-v3.xml text-input-protocol.c diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx index 5b4d97cf2..1cf52a5cd 100644 --- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx @@ -39,6 +39,7 @@ #include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon-compose.h> #include "text-input-client-protocol.h" +#include "gtk-shell-client-protocol.h" #include <assert.h> #include <sys/mman.h> #include <poll.h> @@ -46,7 +47,6 @@ #include <string.h> // for strerror() extern "C" { bool libdecor_get_cursor_settings(char **theme, int *size); - void bind_to_gtk_shell(struct wl_registry *, uint32_t); } @@ -87,6 +87,8 @@ 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 = Fl_Wayland_Screen_Driver::unspecified; @@ -199,6 +201,7 @@ 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) { Fl_Window *win = event_coords_from_surface(surface, surface_x, surface_y); + if (!win && gtk_shell) gtk_shell_surface = surface; if (!win) return; // use custom cursor if present struct wl_cursor *cursor = @@ -220,6 +223,7 @@ static void pointer_leave(void *data, struct wl_pointer *wl_pointer, struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; if (seat->pointer_focus == surface) seat->pointer_focus = NULL; Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(surface); + gtk_shell_surface = NULL; if (win) { Fl::belowmouse(0); set_event_xy(win); @@ -257,6 +261,15 @@ static void pointer_button(void *data, { struct Fl_Wayland_Screen_Driver::seat *seat = (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, + gtk_shell_surface); + gtk_surface1_titlebar_gesture(gtk_surface, serial, seat->wl_seat, + GTK_SURFACE1_GESTURE_MIDDLE_CLICK); + gtk_surface1_release(gtk_surface); + return; + } seat->serial = serial; int event = 0; Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(seat->pointer_focus); @@ -1148,7 +1161,8 @@ 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) { - bind_to_gtk_shell(wl_registry, id); + gtk_shell = (struct gtk_shell1*)wl_registry_bind(wl_registry, id, + >k_shell1_interface, 5); } } else if (strcmp(interface, "weston_desktop_shell") == 0) { Fl_Wayland_Screen_Driver::compositor = Fl_Wayland_Screen_Driver::WESTON; diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index 9082acf51..1345c17a2 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -44,7 +44,6 @@ struct cursor_image { // as in wayland-cursor.c of the Wayland project source co extern "C" { # include "../../../libdecor/src/libdecor-plugin.h" uchar *fl_libdecor_titlebar_buffer(struct libdecor_frame *frame, int *w, int *h, int *stride); - void use_FLTK_pointer_button(struct libdecor_frame *); } #define fl_max(a,b) ((a) > (b) ? (a) : (b)) @@ -854,7 +853,6 @@ static void handle_configure(struct libdecor_frame *frame, #ifdef LIBDECOR_MR131 if (is_1st_run) use_FLTK_toplevel_configure_cb(frame); #endif - use_FLTK_pointer_button(frame); struct wl_output *wl_output = NULL; if (window->fl_win->fullscreen_active()) { if (!(window->state & LIBDECOR_WINDOW_STATE_FULLSCREEN)) { |
