linux-windowing/digesting_libdecor.h

354 lines
9.0 KiB
C

/*
* 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 CLAMP_(a, x, b) CLAMP_BOT(a, CLAMP_TOP(x, 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{
enum header_element type;
GtkWidget *widget;
};
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;
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;
};
// #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 desktop_settings_get_cursor_settings(char **theme, int *size);
enum libdecor_color_scheme desktop_settings_get_color_scheme();
// #include "os-compatibility.h"
int os_create_anonymous_file(off_t size);
// 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;
cairo_surface_t *shadow_blur;
/* 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 close_signal;
EGLDisplay egl_display;
EGLContext egl_context;
EGLSurface egl_surface;
int has_cached_config;
struct libdecor_configuration cached_config;
/* uncategorized experiments */
struct seat *seat;
bool pointer_enter;
bool pointer_leave;
bool pointer_motion;
bool pointer_button;
uint32_t pointer_button_time;
uint32_t pointer_button_button;
uint32_t pointer_button_state;
//struct libdecor_frame_private;
char *title;
Sides2D size_bounds;
struct xdg_toplevel *parent;
int w;
int h;
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;
enum component_slot active;
enum component_slot focus;
enum component_slot grab;
bool csd_active;
struct border_component component_slot[COMPONENT_SLOT_COUNT];
GtkWidget *window;
GtkWidget *header;
struct header_element_data hdr_focus;
bool hdr_focus_is_active;
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;
int csd_show_title_from_state(enum libdecor_window_state state);
int csd_show_shadow_from_state(enum libdecor_window_state state);
static const char *libdecor_gtk_proxy_tag = "libdecor-gtk";
static void draw_header_button(cairo_t *cr, cairo_surface_t *surface, enum header_element button_type);
static enum libdecor_resize_edge edge_from_pos(int x, int y);
static void toggle_maximized(void);
#endif //DIGESTING_LIBDECOR_H