[wayland_gtk_egl] setup and start building a gtk window implementation helper layer

main
Allen Webster 2026-03-03 17:10:16 -08:00
parent b5932166ae
commit e9c46a04f0
6 changed files with 1735 additions and 6 deletions

View File

@ -1,2 +1,2 @@
#!/bin/bash
./wayland_egl.c
./wayland_gtk_egl.c

View File

@ -51,7 +51,6 @@ exit 0
#include <stdbool.h>
#include <cairo/cairo.h>
#include <gtk/gtk.h>
#include "xdg-shell-client-protocol.h"

View File

@ -236,7 +236,7 @@ xdg_toplevel_configure(void *udata, struct xdg_toplevel *xdg_toplevel,
ctx.config_staged.dim[0] = ctx.config.dim[0];
ctx.config_staged.dim[1] = ctx.config.dim[1];
}
ctx.config_staged.flags = window_flags_from_states_array(states);
ctx.config_staged.flags = csd_window_flags_from_states_array(states);
}
static void
@ -683,7 +683,7 @@ csd_impl_calculate_frame(void){
/* wayland helpers */
static WindowFlags
window_flags_from_states_array(struct wl_array *states){
csd_window_flags_from_states_array(struct wl_array *states){
WindowFlags flags = 0;
uint32_t *p;
wl_array_for_each(p, states){

View File

@ -141,10 +141,9 @@ typedef struct Ctx{
static CSD_Frame csd_impl_calculate_frame(void);
/* wayland helpers */
static WindowFlags window_flags_from_states_array(struct wl_array *states);
static WindowFlags csd_window_flags_from_states_array(struct wl_array *states);
/* os */

1511
wayland_gtk_egl.c Executable file

File diff suppressed because it is too large Load Diff

220
wayland_gtk_egl.h Normal file
View File

@ -0,0 +1,220 @@
#ifndef WAYLAND_GTK_EGL_EXAMPLE_H
#define WAYLAND_GTK_EGL_EXAMPLE_H
#define HAS_DBUS
#define HAVE_MEMFD_CREATE
#define HAVE_POSIX_FALLOCATE
#define Min(a, b) ((a)>(b)?(b):(a))
#define Max(a, b) ((a)<(b)?(b):(a))
#define ClampTop(x, a) Min(x, a)
#define ClampBot(x, a) Max(x, a)
typedef enum ColorScheme{
ColorScheme_Default,
ColorScheme_Dark,
ColorScheme_Light
} ColorScheme;
typedef struct CursorTheme{
char *name;
int size;
} CursorTheme;
typedef uint32_t CursorShape;
enum{
CursorShape_Hidden,
CursorShape_Pointer,
CursorShape_Resize_Top,
CursorShape_Resize_Bottom,
CursorShape_Resize_Left,
CursorShape_Resize_Right,
CursorShape_Resize_TopLeft,
CursorShape_Resize_TopRight,
CursorShape_Resize_BottomLeft,
CursorShape_Resize_BottomRight,
CursorShape_COUNT
};
typedef uint32_t WindowFlags;
enum{
WindowFlag_IsFullscreen = (1 << 0),
WindowFlag_IsMax = (1 << 1),
WindowFlag_IsActivated = (1 << 2),
WindowFlag_IsTiledLeft = (1 << 3),
WindowFlag_IsTiledRight = (1 << 4),
WindowFlag_IsTiledTop = (1 << 5),
WindowFlag_IsTiledBottom = (1 << 6),
WindowFlag_IsResizing = (1 << 7),
WindowFlag_IsSuspended = (1 << 8),
WindowFlag_IsConstrainedLeft = (1 << 9),
WindowFlag_IsConstrainedRight = (1 << 10),
WindowFlag_IsConstrainedTop = (1 << 11),
WindowFlag_IsConstrainedBottom = (1 << 12),
};
#define WindowMask_IsAnchored \
(WindowFlag_IsFullscreen|WindowFlag_IsMax| \
WindowFlag_IsTiledLeft |WindowFlag_IsTiledRight| \
WindowFlag_IsTiledTop |WindowFlag_IsTiledBottom)
typedef uint32_t WindowControlFlags;
enum{
WindowControlFlag_Move = (1 << 0),
WindowControlFlag_Resize = (1 << 1),
WindowControlFlag_Min = (1 << 2),
WindowControlFlag_Max = (1 << 3),
WindowControlFlag_Close = (1 << 4),
};
typedef struct Config{
uint32_t serial;
int32_t dim[2];
WindowFlags flags;
uint32_t decoration_mode;
} Config;
typedef struct CSD_Frame{
int32_t border[2][2]; // [0][]:x [1][]:y [][0]:min [][1]:max
int32_t minbox[2];
} CSD_Frame;
typedef struct CSD_SubSurface{
struct wl_surface *wl_surface;
struct wl_subsurface *wl_subsurface;
struct wl_buffer *wl_buffer;
void *data;
uint64_t size;
int32_t dim[2];
int32_t p[2];
} CSD_SubSurface;
typedef struct GTK_Ctx{
cairo_surface_t *shadow_blur;
} GTK_Ctx;
typedef struct GTK_Window{
int32_t p[2];
uint32_t button;
int double_click_time_ms;
CSD_SubSurface titlebar;
CSD_SubSurface shadow;
GtkWidget *window;
GtkWidget *header;
uint32_t hover_button_code;
uint32_t active_button_code;
} GTK_Window;
typedef struct Ctx{
/* "application variables" */
int close_signal;
/* globals: desktop settings */
ColorScheme color_scheme;
CursorTheme cursor_theme;
/* globals: wayland */
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 *zxdg_decoration_manager;
struct wl_cursor_theme *wl_cursor_theme;
struct wl_cursor *wl_cursors[CursorShape_COUNT];
/* globals: egl */
EGLDisplay egl_display;
EGLContext egl_context;
/* globals: gtk */
GTK_Ctx gtk_ctx;
/* per-seat: wayland */
struct wl_seat *wl_seat;
struct wl_pointer *wl_pointer;
struct wl_surface *cursor_surface;
struct wl_surface *hover_surface;
CursorShape cursor_shape;
/* per-window: wayland */
struct wl_surface *main_wl_surface;
struct xdg_surface *main_xdg_surface;
struct xdg_toplevel *main_xdg_toplevel;
struct zxdg_toplevel_decoration_v1 *main_zxdg_toplevel_decoration;
/* per-window: egl */
struct wl_egl_window *main_wl_egl_window;
EGLSurface main_egl_surface;
/* per-window */
WindowControlFlags control_flags;
int32_t dim[2];
int32_t mmbox[2][2]; // [0][]:x [1][]:y [][0]:min [][1]:max
Config config;
Config config_staged;
uint32_t serial;
int handled_first_size;
CSD_Frame csd_frame;
int32_t csd_dim[2];
GTK_Window gtk_window;
} Ctx;
/* csd helpers */
static CSD_SubSurface csd_subsurface_new(void);
static void csd_subsurface_buffer_clear(CSD_SubSurface *subsurface);
static void csd_subsurface_buffer_alloc(CSD_SubSurface *subsurface, int32_t dim[2]);
static void csd_subsurface_set_position(CSD_SubSurface *subsurface, int32_t x, int32_t y);
static void csd_subsurface_commit(CSD_SubSurface *subsurface);
static WindowFlags csd_window_flags_from_states_array(struct wl_array *states);
/* os */
static int os_resize_anonymous_file(int fd, off_t size);
static int os_create_anonymous_file(off_t size);
/* desktop settings */
static CursorTheme ds_get_cursor_theme(void);
static ColorScheme ds_get_color_scheme(void);
static CursorTheme ds__get_cursor_theme_from_env(void);
#if defined(HAS_DBUS)
#include <dbus/dbus.h>
static DBusMessage* ds__get_setting_sync(DBusConnection *const connection, const char *k, const char *v);
static int ds__parse_type(DBusMessage *const reply, const int type, void *value);
#endif /* defined(HAS_DBUS) */
/* csd gtk implementation */
static void csd_gtk_init(void);
static void csd_gtk_window_init(void);
static CSD_Frame csd_gtk_calculate_frame(void);
static void csd_gtk_update_and_render(void);
static void csd_gtk_render(void);
/* cairo shadow rendering */
static int cr_blur_surface(cairo_surface_t *surface, int margin);
static void cr_render_shadow(cairo_t *cr, cairo_surface_t *surface,
int x, int y, int width, int height,
int margin, int top_margin);
#endif /* WAYLAND_GTK_EGL_EXAMPLE_H */