/* * Copyright © 2012 Collabora, Ltd. * Copyright © 2012 Intel Corporation * Copyright © 2017-2018 Red Hat Inc. * Copyright © 2018 Jonas Ådahl * Copyright © 2021 Christian Rauch * Copyright © 2024 Colin Kinloch * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial * portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef DIGESTING_LIBDECOR_H #define DIGESTING_LIBDECOR_H // config.h #define HAS_DBUS /* #undef HAVE_MKOSTEMP */ #define HAVE_POSIX_FALLOCATE #define HAVE_MEMFD_CREATE #define HAVE_GETTID // utils.h #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define CLAMP_BOT(a, b) MAX(a, b) #define CLAMP_TOP(a, b) MIN(a, b) #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) #define STREQL(a,b) (((a)==0 && (b)==0) || \ ((a)!=0 && (b)!=0 && strcmp((a),(b))==0)) // mine typedef struct Extent2D{ int x; int y; int w; int h; } Extent2D; typedef struct Sides2D{ int x[2]; int y[2]; } Sides2D; // libdecor.h struct libdecor_configuration; struct libdecor_state; enum libdecor_error { LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE, LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION, }; enum libdecor_window_state { LIBDECOR_WINDOW_STATE_NONE = 0, LIBDECOR_WINDOW_STATE_ACTIVE = 1 << 0, LIBDECOR_WINDOW_STATE_MAXIMIZED = 1 << 1, LIBDECOR_WINDOW_STATE_FULLSCREEN = 1 << 2, LIBDECOR_WINDOW_STATE_TILED_LEFT = 1 << 3, LIBDECOR_WINDOW_STATE_TILED_RIGHT = 1 << 4, LIBDECOR_WINDOW_STATE_TILED_TOP = 1 << 5, LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 1 << 6, LIBDECOR_WINDOW_STATE_SUSPENDED = 1 << 7, LIBDECOR_WINDOW_STATE_RESIZING = 1 << 8, LIBDECOR_WINDOW_STATE_CONSTRAINED_LEFT = 1 << 9, LIBDECOR_WINDOW_STATE_CONSTRAINED_RIGHT = 1 << 10, LIBDECOR_WINDOW_STATE_CONSTRAINED_TOP = 1 << 11, LIBDECOR_WINDOW_STATE_CONSTRAINED_BOTTOM = 1 << 12, }; #define LIBDECOR_WINDOW_STATE_NON_FLOATING (LIBDECOR_WINDOW_STATE_MAXIMIZED |\ LIBDECOR_WINDOW_STATE_FULLSCREEN |\ LIBDECOR_WINDOW_STATE_TILED_LEFT |\ LIBDECOR_WINDOW_STATE_TILED_RIGHT |\ LIBDECOR_WINDOW_STATE_TILED_TOP |\ LIBDECOR_WINDOW_STATE_TILED_BOTTOM) enum libdecor_resize_edge { LIBDECOR_RESIZE_EDGE_NONE, LIBDECOR_RESIZE_EDGE_TOP, LIBDECOR_RESIZE_EDGE_BOTTOM, LIBDECOR_RESIZE_EDGE_LEFT, LIBDECOR_RESIZE_EDGE_TOP_LEFT, LIBDECOR_RESIZE_EDGE_BOTTOM_LEFT, LIBDECOR_RESIZE_EDGE_RIGHT, LIBDECOR_RESIZE_EDGE_TOP_RIGHT, LIBDECOR_RESIZE_EDGE_BOTTOM_RIGHT, }; enum libdecor_capabilities { LIBDECOR_ACTION_MOVE = 1 << 0, LIBDECOR_ACTION_RESIZE = 1 << 1, LIBDECOR_ACTION_MINIMIZE = 1 << 2, LIBDECOR_ACTION_FULLSCREEN = 1 << 3, LIBDECOR_ACTION_CLOSE = 1 << 4, }; enum libdecor_wm_capabilities { LIBDECOR_WM_CAPABILITIES_WINDOW_MENU = 1 << 0, LIBDECOR_WM_CAPABILITIES_MAXIMIZE = 1 << 1, LIBDECOR_WM_CAPABILITIES_FULLSCREEN = 1 << 2, LIBDECOR_WM_CAPABILITIES_MINIMIZE = 1 << 3 }; // libdecor-plugin.h enum header_element { HEADER_NONE, HEADER_FULL, /* entire header bar */ HEADER_TITLE, /* label */ HEADER_MIN, HEADER_MAX, HEADER_CLOSE, }; enum titlebar_gesture_state { TITLEBAR_GESTURE_STATE_INIT, TITLEBAR_GESTURE_STATE_BUTTON_PRESSED, TITLEBAR_GESTURE_STATE_CONSUMED, TITLEBAR_GESTURE_STATE_DISCARDED, }; struct header_element_data { const char *name; enum header_element type; GtkWidget *widget; GtkStateFlags state; }; enum decoration_type { DECORATION_TYPE_NONE, DECORATION_TYPE_ALL, DECORATION_TYPE_TITLE_ONLY }; enum component_slot { COMPONENT_SLOT_NONE, COMPONENT_SLOT_SHADOW, COMPONENT_SLOT_HEADER, COMPONENT_SLOT_COUNT }; struct border_component { struct wl_surface *wl_surface; struct wl_subsurface *wl_subsurface; bool opaque; struct wl_buffer *wl_buffer; void *data; size_t data_size; int width; int height; }; // #include "libdecor.c" struct libdecor_state { enum libdecor_window_state window_state; int content_width; int content_height; }; struct libdecor_configuration{ bool initialized; uint32_t serial; enum libdecor_window_state window_state; int window_width; int window_height; }; // #include "desktop-settings.h" enum libdecor_color_scheme { LIBDECOR_COLOR_SCHEME_DEFAULT, LIBDECOR_COLOR_SCHEME_PREFER_DARK, LIBDECOR_COLOR_SCHEME_PREFER_LIGHT, }; // #include "plugins/gtk/libdecor-gtk.c" static const size_t SHADOW_MARGIN = 24; static const char *cursor_names[] = { "top_side", "bottom_side", "left_side", "top_left_corner", "bottom_left_corner", "right_side", "top_right_corner", "bottom_right_corner" }; struct seat { 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; struct wl_surface *pointer_focus; struct wl_surface *touch_focus; int pointer_x; int pointer_y; uint32_t touch_down_time_stamp; uint32_t serial; bool grabbed; struct wl_list link; }; enum titlebar_gesture { TITLEBAR_GESTURE_DOUBLE_CLICK, TITLEBAR_GESTURE_MIDDLE_CLICK, TITLEBAR_GESTURE_RIGHT_CLICK, }; // libdecor.h void libdecor_frame_show_window_menu(struct wl_seat *wl_seat, uint32_t serial, int x, int y); void libdecor_frame_commit(void); void libdecor_frame_set_fullscreen(struct wl_output *output); void libdecor_frame_unset_fullscreen(void); // #include "libdecor-cairo-blur.h" int blur_surface(cairo_surface_t *surface, int margin); void render_shadow(cairo_t *cr, cairo_surface_t *surface, int x, int y, int width, int height, int margin, int top_margin); // #include "desktop-settings.h" bool libdecor_get_cursor_settings(char **theme, int *size); enum libdecor_color_scheme libdecor_get_color_scheme(); // #include "os-compatibility.h" int libdecor_os_create_anonymous_file(off_t size); // #include "libdecor.c" static void init_shell_surface(void); static void do_map(void); // #include "plugins/gtk/libdecor-gtk.c" static const char *libdecor_gtk_proxy_tag = "libdecor-gtk"; static void libdecor_plugin_gtk_frame_free(void); static void libdecor_plugin_gtk_frame_commit(void); static Sides2D border_size_from_window_state(enum libdecor_window_state window_state); static struct wl_cursor* wl_cursor_from_pos(int x, int y); static void draw_decoration(void); static void draw_header_button(cairo_t *cr, cairo_surface_t *surface, enum header_element button_type); static void draw_border_component(enum component_slot slot); static bool own_proxy(void *proxy); static enum component_slot component_slot_from_wl_surface(const struct wl_surface *surface); static struct header_element_data get_header_focus(const GtkHeaderBar *header_bar, int x, int y); static void draw_title_bar(void); static enum libdecor_resize_edge edge_from_pos(int x, int y); static void toggle_maximized(void); static void update_touch_focus(struct seat *seat, wl_fixed_t x, wl_fixed_t y); static enum xdg_toplevel_resize_edge xdg_edge_from_edge(enum libdecor_resize_edge edge); // digesting_libdecor typedef struct Ctx{ /* desktop settings */ enum libdecor_color_scheme color_scheme; char *cursor_theme_name; int cursor_size; /* globals */ struct wl_display *wl_display; struct wl_registry *wl_registry; struct wl_compositor *wl_compositor; struct wl_subcompositor *wl_subcompositor; struct wl_shm *wl_shm; struct xdg_wm_base *xdg_wm_base; struct zxdg_decoration_manager_v1 *decoration_manager; struct wl_cursor_theme *cursor_theme; struct wl_cursor *cursors[ARRAY_LENGTH(cursor_names)]; struct wl_cursor *cursor_left_ptr; struct wl_list seat_list; bool has_error; bool has_argb; int double_click_time_ms; int drag_threshold; /* window */ struct wl_surface *wl_surface; struct xdg_surface *xdg_surface; struct xdg_toplevel *xdg_toplevel; struct zxdg_toplevel_decoration_v1 *toplevel_decoration; struct wl_egl_window *wl_egl_window; int w; int h; int close_signal; EGLDisplay egl_display; EGLContext egl_context; EGLSurface egl_surface; int has_cached_config; struct libdecor_configuration cached_config; int has_pending_config; struct libdecor_configuration pending_config; //struct libdecor_frame_private; char *title; Sides2D size_bounds; struct xdg_toplevel *parent; int frame_content_width; int frame_content_height; enum libdecor_window_state frame_window_state; bool has_decoration_mode; enum zxdg_toplevel_decoration_v1_mode decoration_mode; enum libdecor_capabilities frame_capabilities; enum libdecor_wm_capabilities wm_capabilities; bool visible; //struct libdecor_frame_gtk; int gtk_content_width; int gtk_content_height; enum libdecor_window_state gtk_window_state; enum decoration_type decoration_type; enum libdecor_capabilities gtk_capabilities; enum component_slot active; enum component_slot touch_active; enum component_slot focus; enum component_slot grab; struct border_component component_slot[COMPONENT_SLOT_COUNT]; bool shadow_showing; GtkWidget *window; GtkWidget *header; struct header_element_data hdr_focus; cairo_surface_t *shadow_blur; struct { enum titlebar_gesture_state state; int button_pressed_count; uint32_t first_pressed_button; uint32_t first_pressed_time; int pressed_x; int pressed_y; uint32_t serial; } titlebar_gesture; } Ctx; #endif //DIGESTING_LIBDECOR_H