[digesting_libdecor] eliminate dead code and reducible context variables, deduplicate cursor update logic a bit

main
Allen Webster 2026-03-02 11:28:22 -08:00
parent 458b0bcb55
commit 2770ddc39b
2 changed files with 81 additions and 209 deletions

View File

@ -346,8 +346,8 @@ xdg_toplevel_decoration_listener = { xdg_toplevel_decoration_configure, };
int main(){
/* get desktop settings */
ctx.color_scheme = libdecor_get_color_scheme();
if (libdecor_get_cursor_settings(&ctx.cursor_theme_name, &ctx.cursor_size)){
ctx.color_scheme = desktop_settings_get_color_scheme();
if (desktop_settings_get_cursor_settings(&ctx.cursor_theme_name, &ctx.cursor_size)){
ctx.cursor_theme_name = 0;
ctx.cursor_size = 24;
}
@ -370,10 +370,7 @@ int main(){
}
}
/*~ NOTE:
**~ initialize Wayland, Libdecor, & EGL
*/
/* initialize Wayland, & EGL */
{
ctx.w = 640;
ctx.h = 480;
@ -425,19 +422,29 @@ int main(){
}
}
if (!ctx.has_error){
static const int size = 128;
static const int boundary = 32;
cairo_surface_t *shadow_blur =
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, size, size);
cairo_t *cr = cairo_create(shadow_blur);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_set_source_rgba(cr, 0, 0, 0, 1);
cairo_rectangle(cr, boundary, boundary, size - 2*boundary, size - 2*boundary);
cairo_fill(cr);
cairo_destroy(cr);
blur_surface(shadow_blur, 64);
ctx.shadow_blur = shadow_blur;
}
int opengl_load_success = 0;
if (!ctx.has_error){
/* (egl) eglGetDisplay
** " obtains the EGL display connection for the native display "
*/
ctx.egl_display = eglGetDisplay(ctx.wl_display);
if (ctx.egl_display == 0){
printf("eglGetDisplay failed\n");
}
/* (egl) eglInitialize
** " initializes* the EGL display connection obtained with eglGetDisplay "
*/
int egl_init_success = 0;
EGLint major = 0, minor = 0;
if (ctx.egl_display != 0){
@ -456,19 +463,11 @@ int main(){
}
}
/* (egl) eglBindAPI
** " defines the current rendering API for EGL in the thread it is
** called from "
*/
EGLBoolean bind_api_success = 0;
if (egl_init_success){
bind_api_success = eglBindAPI(EGL_OPENGL_API);
}
/* (egl) eglCreateContext
** " creates an EGL rendering context for the current rendering API
** (as set with eglBindAPI) and returns a handle to the context "
*/
if (bind_api_success){
EGLint attr[] = {
EGL_CONTEXT_MAJOR_VERSION, 3,
@ -482,9 +481,6 @@ int main(){
}
}
/* (egl) eglMakeCurrent
** " binds context to the current rendering thread "
*/
EGLBoolean make_current_success = 0;
if (ctx.egl_context != 0){
make_current_success = eglMakeCurrent(ctx.egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx.egl_context);
@ -493,9 +489,6 @@ int main(){
}
}
/* (egl) eglGetProcAddress
** " returns the address of the client API or EGL function "
*/
if (make_current_success){
opengl_load_success = 1;
#define X(N,R,P) N = (R(*)P)(eglGetProcAddress(#N)); if (N == 0) opengl_load_success = 0;
@ -507,14 +500,9 @@ int main(){
}
}
/*~ NOTE:
**~ Create a window
*/
/* create a window */
if (opengl_load_success){
/* (1) Appendix A: wl_compositor::create_surface
** " create new surface "
*/
ctx.wl_surface = wl_compositor_create_surface(ctx.wl_compositor);
if (ctx.wl_surface == 0){
printf("wl_compositor_create_surface failed\n");
@ -522,22 +510,6 @@ int main(){
}
if (ctx.wl_surface != 0){
{
static const int size = 128;
static const int boundary = 32;
cairo_surface_t *shadow_blur =
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, size, size);
cairo_t *cr = cairo_create(shadow_blur);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_set_source_rgba(cr, 0, 0, 0, 1);
cairo_rectangle(cr, boundary, boundary, size - 2*boundary, size - 2*boundary);
cairo_fill(cr);
cairo_destroy(cr);
blur_surface(shadow_blur, 64);
ctx.shadow_blur = shadow_blur;
}
ctx.visible = true;
ctx.wm_capabilities = (LIBDECOR_WM_CAPABILITIES_WINDOW_MENU |
LIBDECOR_WM_CAPABILITIES_MAXIMIZE |
@ -572,7 +544,6 @@ int main(){
wl_surface_commit(ctx.wl_surface);
/* (nodocs-wl_egl) */
ctx.wl_egl_window = wl_egl_window_create(ctx.wl_surface, ctx.w, ctx.h);
if (ctx.wl_egl_window == EGL_NO_SURFACE){
printf("wl_egl_window_create failed\n");
@ -580,10 +551,6 @@ int main(){
}
if (ctx.wl_egl_window != EGL_NO_SURFACE){
/* (nodocs-wl_egl) eglChooseConfig
** " returns in configs a list of all EGL frame buffer configurations
** that match the attributes specified in attrib_list "
*/
EGLConfig configs[64];
EGLint config_cap = sizeof(configs)/sizeof(*configs);
EGLint config_count = 0;
@ -606,9 +573,6 @@ int main(){
}
}
/* (egl) eglCreateWindowSurface
** " creates an on-screen EGL window surface and returns a handle to it "
*/
{
EGLint attributes[] = {
EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
@ -639,7 +603,7 @@ int main(){
}
}
/*~ NOTE: Main loop */
/* main loop */
int exit_loop = 0;
if (!swap_interval_success){
exit_loop = 1;
@ -684,25 +648,6 @@ int main(){
}
/* re-render cursor */
if (ctx.pointer_leave){
ctx.pointer_leave = 0;
ctx.titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT;
ctx.titlebar_gesture.first_pressed_button = 0;
ctx.hdr_focus.widget = 0;
ctx.hdr_focus.type = HEADER_NONE;
draw_decoration();
wl_surface_commit(ctx.wl_surface);
ctx.seat->current_cursor = wl_cursor_from_pos(ctx.seat->pointer_x, ctx.seat->pointer_y);
}
if (ctx.pointer_enter){
ctx.pointer_enter = 0;
if (ctx.active != 0){
draw_decoration();
wl_surface_commit(ctx.wl_surface);
}
ctx.seat->current_cursor = wl_cursor_from_pos(ctx.seat->pointer_x, ctx.seat->pointer_y);
if (ctx.seat->current_cursor != 0){
struct wl_cursor_image *image = ctx.seat->current_cursor->images[0];
@ -713,21 +658,28 @@ int main(){
wl_surface_commit(ctx.seat->cursor_surface);
wl_pointer_set_cursor(ctx.seat->wl_pointer, ctx.seat->serial, ctx.seat->cursor_surface, image->hotspot_x, image->hotspot_y);
}
if (ctx.pointer_leave){
ctx.pointer_leave = 0;
ctx.titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT;
ctx.titlebar_gesture.first_pressed_button = 0;
ctx.hdr_focus.widget = 0;
ctx.hdr_focus.type = HEADER_NONE;
draw_decoration();
wl_surface_commit(ctx.wl_surface);
}
if (ctx.pointer_enter){
ctx.pointer_enter = 0;
if (ctx.active != 0){
draw_decoration();
wl_surface_commit(ctx.wl_surface);
}
}
if (ctx.pointer_motion){
ctx.pointer_motion = 0;
ctx.seat->current_cursor = wl_cursor_from_pos(ctx.seat->pointer_x, ctx.seat->pointer_y);
if (ctx.seat->current_cursor != 0){
struct wl_cursor_image *image = ctx.seat->current_cursor->images[0];
struct wl_buffer *buffer = wl_cursor_image_get_buffer(image);
wl_surface_attach(ctx.seat->cursor_surface, buffer, 0, 0);
wl_surface_set_buffer_scale(ctx.seat->cursor_surface, 1);
wl_surface_damage_buffer(ctx.seat->cursor_surface, 0, 0, image->width, image->height);
wl_surface_commit(ctx.seat->cursor_surface);
wl_pointer_set_cursor(ctx.seat->wl_pointer, ctx.seat->serial, ctx.seat->cursor_surface,
image->hotspot_x, image->hotspot_y);
}
if (!GTK_IS_WIDGET(ctx.header) || ctx.active != COMPONENT_SLOT_HEADER){
ctx.hdr_focus.type = HEADER_NONE;
@ -762,7 +714,19 @@ int main(){
enum libdecor_resize_edge edge = edge_from_pos(ctx.seat->pointer_x, ctx.seat->pointer_y);
if (edge != LIBDECOR_RESIZE_EDGE_NONE &&
(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
xdg_toplevel_resize(ctx.xdg_toplevel, ctx.seat->wl_seat, ctx.seat->serial, xdg_edge_from_edge(edge));
enum xdg_toplevel_resize_edge xedge = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
switch (edge) {
default: case LIBDECOR_RESIZE_EDGE_NONE: break;
case LIBDECOR_RESIZE_EDGE_TOP: xedge = XDG_TOPLEVEL_RESIZE_EDGE_TOP; break;
case LIBDECOR_RESIZE_EDGE_BOTTOM: xedge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM; break;
case LIBDECOR_RESIZE_EDGE_LEFT: xedge = XDG_TOPLEVEL_RESIZE_EDGE_LEFT; break;
case LIBDECOR_RESIZE_EDGE_TOP_LEFT: xedge = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT; break;
case LIBDECOR_RESIZE_EDGE_BOTTOM_LEFT: xedge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT; break;
case LIBDECOR_RESIZE_EDGE_RIGHT: xedge = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT; break;
case LIBDECOR_RESIZE_EDGE_TOP_RIGHT: xedge = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT; break;
case LIBDECOR_RESIZE_EDGE_BOTTOM_RIGHT: xedge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT; break;
}
xdg_toplevel_resize(ctx.xdg_toplevel, ctx.seat->wl_seat, ctx.seat->serial, xedge);
}
}break;
@ -923,35 +887,30 @@ int main(){
if (ctx.cached_config.initialized){
ctx.frame_window_state = ctx.cached_config.window_state;
}
ctx.frame_content_width = ctx.w;
ctx.frame_content_height = ctx.h;
libdecor_frame_commit();
frame_commit();
xdg_surface_ack_configure(ctx.xdg_surface, ctx.cached_config.serial);
}
wl_egl_window_resize(ctx.wl_egl_window, ctx.w, ctx.h, 0, 0);
/* app update & render */
{
if (ctx.close_signal){
exit_loop = 1;
}
glDrawBuffer(GL_BACK);
glViewport(0, 0, 640, 480);
glClearColor(0.40f, 0.90f, 0.15f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
}
if (ctx.close_signal){
exit_loop = 1;
}
EGLBoolean swap_success = eglSwapBuffers(ctx.egl_display, ctx.egl_surface);
if (!swap_success){
printf("eglSwapBuffers failed\n");
}
}
if (ctx.wl_display != 0){
wl_display_disconnect(ctx.wl_display);
}
return(0);
}
@ -1005,25 +964,8 @@ decoration_type_from_window_state(enum libdecor_window_state window_state){
return(result);
}
static enum xdg_toplevel_resize_edge
xdg_edge_from_edge(enum libdecor_resize_edge edge){
enum xdg_toplevel_resize_edge result = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
switch (edge) {
default: case LIBDECOR_RESIZE_EDGE_NONE: break;
case LIBDECOR_RESIZE_EDGE_TOP: result = XDG_TOPLEVEL_RESIZE_EDGE_TOP; break;
case LIBDECOR_RESIZE_EDGE_BOTTOM: result = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM; break;
case LIBDECOR_RESIZE_EDGE_LEFT: result = XDG_TOPLEVEL_RESIZE_EDGE_LEFT; break;
case LIBDECOR_RESIZE_EDGE_TOP_LEFT: result = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT; break;
case LIBDECOR_RESIZE_EDGE_BOTTOM_LEFT: result = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT; break;
case LIBDECOR_RESIZE_EDGE_RIGHT: result = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT; break;
case LIBDECOR_RESIZE_EDGE_TOP_RIGHT: result = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT; break;
case LIBDECOR_RESIZE_EDGE_BOTTOM_RIGHT: result = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT; break;
}
return(result);
}
void
libdecor_frame_commit(void){
frame_commit(void){
bool csd = false;
if (ctx.visible &&
ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){
@ -1036,10 +978,8 @@ libdecor_frame_commit(void){
}
if (!(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
int mw = ctx.frame_content_width;
int mh = ctx.frame_content_height;
xdg_toplevel_set_min_size(ctx.xdg_toplevel, mw, mh);
xdg_toplevel_set_max_size(ctx.xdg_toplevel, mw, mh);
xdg_toplevel_set_min_size(ctx.xdg_toplevel, ctx.w, ctx.h);
xdg_toplevel_set_max_size(ctx.xdg_toplevel, ctx.w, ctx.h);
}
else{
@ -1066,11 +1006,7 @@ libdecor_frame_commit(void){
}
if (csd){
ctx.gtk_content_width = ctx.frame_content_width;
ctx.gtk_content_height = ctx.frame_content_height;
ctx.gtk_window_state = ctx.frame_window_state;
ctx.decoration_type = decoration_type_from_window_state(ctx.frame_window_state);
draw_decoration();
}
else{
@ -1108,8 +1044,8 @@ libdecor_frame_commit(void){
{
Extent2D extent = {0};
extent.w = ctx.frame_content_width;
extent.h = ctx.frame_content_height;
extent.w = ctx.w;
extent.h = ctx.h;
if (csd){
extent.x = -border_size.x[0];
extent.y = -border_size.y[0];
@ -1121,42 +1057,6 @@ libdecor_frame_commit(void){
}
}
void
cleanup(void){
{
struct seat *seat, *seat_tmp;
wl_list_for_each_safe(seat, seat_tmp, &ctx.seat_list, link) {
if (seat->wl_pointer){
wl_pointer_destroy(seat->wl_pointer);
}
wl_surface_destroy(seat->cursor_surface);
wl_seat_destroy(seat->wl_seat);
if (ctx.cursor_theme != 0){
wl_cursor_theme_destroy(ctx.cursor_theme);
}
if (seat->name != 0){
free(seat->name);
}
free(seat);
}
}
if (ctx.wl_shm){
wl_shm_destroy(ctx.wl_shm);
}
if (ctx.wl_subcompositor != 0){
wl_subcompositor_destroy(ctx.wl_subcompositor);
}
if (ctx.xdg_wm_base != 0){
xdg_wm_base_destroy(ctx.xdg_wm_base);
}
if (ctx.decoration_manager != 0){
zxdg_decoration_manager_v1_destroy(ctx.decoration_manager);
}
}
//#include "libdecor-cairo-blur.c"
int
blur_surface(cairo_surface_t *surface, int margin){
@ -1447,8 +1347,8 @@ os_resize_anonymous_file(int fd, off_t size){
#endif
}
int
libdecor_os_create_anonymous_file(off_t size){
int os_create_anonymous_file(off_t size){
static const char key[] = "/libdecor-shared-XXXXXX";
int fd = -1;
@ -1643,8 +1543,6 @@ ensure_title_bar_surfaces(void){
static Extent2D
extent2d_from_component_slot(enum component_slot slot){
Extent2D result = {0};
int width = ctx.frame_content_width;
int height = ctx.frame_content_height;
int title_height = 0;
if (GTK_IS_WIDGET(ctx.header)){
@ -1657,8 +1555,8 @@ extent2d_from_component_slot(enum component_slot slot){
case COMPONENT_SLOT_SHADOW: {
result.x = -(int)SHADOW_MARGIN;
result.y = -(int)(SHADOW_MARGIN + title_height);
result.w = width + 2*SHADOW_MARGIN;
result.h = title_height + height + 2*SHADOW_MARGIN;
result.w = ctx.w + 2*SHADOW_MARGIN;
result.h = title_height + ctx.h + 2*SHADOW_MARGIN;
}break;
case COMPONENT_SLOT_HEADER: {
@ -1672,13 +1570,6 @@ extent2d_from_component_slot(enum component_slot slot){
return(result);
}
static void
array_append(enum header_element **array, size_t *n, enum header_element item){
(*n)++;
*array = realloc(*array, (*n) * sizeof (enum header_element));
(*array)[(*n)-1] = item;
}
static void
draw_header_button(cairo_t *cr, cairo_surface_t *surface,
enum header_element button_type){
@ -1825,7 +1716,7 @@ draw_border_component(enum component_slot slot){
Extent2D extent = extent2d_from_component_slot(COMPONENT_SLOT_SHADOW);
input_region = wl_compositor_create_region(ctx.wl_compositor);
wl_region_add(input_region, 0, 0, extent.w, extent.h);
wl_region_subtract(input_region, -extent.x, -extent.y, ctx.frame_content_width, ctx.frame_content_height);
wl_region_subtract(input_region, -extent.x, -extent.y, ctx.w, ctx.h);
wl_surface_set_input_region(component->wl_surface, input_region);
wl_region_destroy(input_region);
}
@ -1851,7 +1742,7 @@ draw_border_component(enum component_slot slot){
int stride = 4*width;
int size = stride*height;
int fd = libdecor_os_create_anonymous_file(size);
int fd = os_create_anonymous_file(size);
if (fd >= 0){
void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (data != MAP_FAILED){
@ -1890,7 +1781,7 @@ draw_border_component(enum component_slot slot){
component->width + SHADOW_MARGIN, component->height + SHADOW_MARGIN,
64, 64);
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
cairo_rectangle(cr, -extent.x, -extent.y, ctx.frame_content_width, ctx.frame_content_height);
cairo_rectangle(cr, -extent.x, -extent.y, ctx.w, ctx.h);
cairo_fill(cr);
}break;
@ -1991,16 +1882,12 @@ draw_title_bar(void){
ctx.size_bounds.x[1] = CLAMP_BOT(ctx.size_bounds.x[1], ctx.size_bounds.x[0]);
}
int w = ctx.frame_content_width;
int h = ctx.frame_content_height;
if (w < ctx.size_bounds.x[0]){
w = ctx.size_bounds.x[0];
ctx.frame_content_width = w;
ctx.frame_content_height = h;
libdecor_frame_commit();
if (ctx.w < ctx.size_bounds.x[0]){
ctx.w = ctx.size_bounds.x[0];
frame_commit();
}
else{
GtkAllocation allocation = {0, 0, ctx.gtk_content_width, 0};
GtkAllocation allocation = {0, 0, ctx.w, 0};
gtk_widget_get_preferred_height(ctx.header, 0, &allocation.height);
gtk_widget_size_allocate(ctx.header, &allocation);
draw_border_component(COMPONENT_SLOT_HEADER);
@ -2164,7 +2051,7 @@ parse_type(DBusMessage *const reply, const int type, void *value){
}
bool
libdecor_get_cursor_settings(char **theme, int *size){
desktop_settings_get_cursor_settings(char **theme, int *size){
static const char name[] = "org.gnome.desktop.interface";
static const char key_theme[] = "cursor-theme";
static const char key_size[] = "cursor-size";
@ -2206,7 +2093,7 @@ libdecor_get_cursor_settings(char **theme, int *size){
}
enum libdecor_color_scheme
libdecor_get_color_scheme(){
desktop_settings_get_color_scheme(){
static const char name[] = "org.freedesktop.appearance";
static const char key_color_scheme[] = "color-scheme";
uint32_t color = 0;
@ -2234,12 +2121,12 @@ libdecor_get_color_scheme(){
#else
bool
libdecor_get_cursor_settings(char **theme, int *size){
desktop_settings_get_cursor_settings(char **theme, int *size){
return(get_cursor_settings_from_env(theme, size));
}
uint32_t
libdecor_get_color_scheme(){
desktop_settings_get_color_scheme(){
return(LIBDECOR_COLOR_SCHEME_DEFAULT);
}

View File

@ -215,7 +215,7 @@ static const char *cursor_names[] = {
"bottom_right_corner"
};
struct seat {
struct seat{
char *name;
struct wl_seat *wl_seat;
@ -240,7 +240,7 @@ struct seat {
struct wl_list link;
};
enum titlebar_gesture {
enum titlebar_gesture{
TITLEBAR_GESTURE_DOUBLE_CLICK,
TITLEBAR_GESTURE_MIDDLE_CLICK,
TITLEBAR_GESTURE_RIGHT_CLICK,
@ -248,24 +248,20 @@ enum titlebar_gesture {
// 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 frame_commit(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();
bool desktop_settings_get_cursor_settings(char **theme, int *size);
enum libdecor_color_scheme desktop_settings_get_color_scheme();
// #include "os-compatibility.h"
int libdecor_os_create_anonymous_file(off_t size);
int os_create_anonymous_file(off_t size);
// #include "libdecor.c"
@ -292,8 +288,6 @@ 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{
@ -323,14 +317,14 @@ typedef struct Ctx{
int double_click_time_ms;
int drag_threshold;
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 w;
int h;
int close_signal;
EGLDisplay egl_display;
EGLContext egl_context;
@ -354,8 +348,8 @@ typedef struct Ctx{
Sides2D size_bounds;
struct xdg_toplevel *parent;
int frame_content_width;
int frame_content_height;
int w;
int h;
enum libdecor_window_state frame_window_state;
@ -368,15 +362,8 @@ typedef struct Ctx{
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 focus;
enum component_slot grab;
@ -388,8 +375,6 @@ typedef struct Ctx{
struct header_element_data hdr_focus;
GtkStateFlags hdr_state;
cairo_surface_t *shadow_blur;
struct {
enum titlebar_gesture_state state;
int button_pressed_count;