[digesting_libdecor] bake in shadow component to edge_from_pos (formally component_edge), fix bug in edge calculation

main
Allen Webster 2026-02-28 11:54:21 -08:00
parent e0498157b9
commit 1c78761080
2 changed files with 51 additions and 61 deletions

View File

@ -93,14 +93,14 @@ const struct wl_shm_listener shm_listener = { shm_format };
static void static void
pointer_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, 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){ struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y){
struct seat *seat = data; struct seat *seat = data;
if (seat->cursor_surface == 0){ if (seat->cursor_surface == 0){
seat->cursor_surface = wl_compositor_create_surface(ctx.wl_compositor); seat->cursor_surface = wl_compositor_create_surface(ctx.wl_compositor);
} }
seat->pointer_x = wl_fixed_to_int(surface_x); seat->pointer_x = wl_fixed_to_int(x);
seat->pointer_y = wl_fixed_to_int(surface_y); seat->pointer_y = wl_fixed_to_int(y);
seat->serial = serial; seat->serial = serial;
seat->pointer_focus = surface; seat->pointer_focus = surface;
@ -169,11 +169,10 @@ pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time,
ctx.hdr_focus.type = HEADER_NONE; ctx.hdr_focus.type = HEADER_NONE;
} }
new_focus = get_header_focus(GTK_HEADER_BAR(ctx.header), new_focus = get_header_focus(GTK_HEADER_BAR(ctx.header), seat->pointer_x, seat->pointer_y);
seat->pointer_x, seat->pointer_y);
/* only update if widget change so that we keep the state */ /* only update if widget change so that we keep the state */
if (ctx.hdr_focus.widget != new_focus.widget) { if (ctx.hdr_focus.widget != new_focus.widget){
ctx.hdr_focus = new_focus; ctx.hdr_focus = new_focus;
} }
ctx.hdr_focus.state |= GTK_STATE_FLAG_PRELIGHT; ctx.hdr_focus.state |= GTK_STATE_FLAG_PRELIGHT;
@ -200,7 +199,7 @@ pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial,
if (seat->pointer_focus && own_proxy(seat->pointer_focus)){ if (seat->pointer_focus && own_proxy(seat->pointer_focus)){
switch (ctx.active){ switch (ctx.active){
case COMPONENT_SLOT_SHADOW: { case COMPONENT_SLOT_SHADOW: {
enum libdecor_resize_edge edge = component_edge(COMPONENT_SLOT_SHADOW, seat->pointer_x, seat->pointer_y); enum libdecor_resize_edge edge = edge_from_pos(seat->pointer_x, seat->pointer_y);
if (edge != LIBDECOR_RESIZE_EDGE_NONE && if (edge != LIBDECOR_RESIZE_EDGE_NONE &&
(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
xdg_toplevel_resize(ctx.xdg_toplevel, seat->wl_seat, serial, xdg_edge_from_edge(edge)); xdg_toplevel_resize(ctx.xdg_toplevel, seat->wl_seat, serial, xdg_edge_from_edge(edge));
@ -357,7 +356,7 @@ touch_down(void *data, struct wl_touch *wl_touch, uint32_t serial,
switch (ctx.touch_active){ switch (ctx.touch_active){
case COMPONENT_SLOT_SHADOW: { case COMPONENT_SLOT_SHADOW: {
enum libdecor_resize_edge edge = component_edge(COMPONENT_SLOT_SHADOW, wl_fixed_to_int(x), wl_fixed_to_int(y)); enum libdecor_resize_edge edge = edge_from_pos(wl_fixed_to_int(x), wl_fixed_to_int(y));
if (edge != LIBDECOR_RESIZE_EDGE_NONE && if (edge != LIBDECOR_RESIZE_EDGE_NONE &&
(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
xdg_toplevel_resize(ctx.xdg_toplevel, seat->wl_seat, serial, xdg_edge_from_edge(edge)); xdg_toplevel_resize(ctx.xdg_toplevel, seat->wl_seat, serial, xdg_edge_from_edge(edge));
@ -549,6 +548,8 @@ wl_registry_global(void *data, struct wl_registry *wl_registry,
wl_list_insert(&ctx.seat_list, &seat->link); wl_list_insert(&ctx.seat_list, &seat->link);
seat->wl_seat = wl_registry_bind(ctx.wl_registry, name, &wl_seat_interface, 3); seat->wl_seat = wl_registry_bind(ctx.wl_registry, name, &wl_seat_interface, 3);
wl_seat_add_listener(seat->wl_seat, &seat_listener, seat); wl_seat_add_listener(seat->wl_seat, &seat_listener, seat);
} }
} }
@ -1747,21 +1748,22 @@ libdecor_os_create_anonymous_file(off_t size){
//#include "plugins/gtk/libdecor-gtk.c" //#include "plugins/gtk/libdecor-gtk.c"
static void static void
find_widget_by_name(GtkWidget *widget, void *data){ gtk_fill_widget_from_name(GtkWidget *widget, void *data){
bool match = false;
if (GTK_IS_WIDGET(widget)){ if (GTK_IS_WIDGET(widget)){
char *style_ctx = gtk_style_context_to_string(gtk_widget_get_style_context(widget), struct header_element_data *elem = data;
GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE); GtkStyleContext *style_context = gtk_widget_get_style_context(widget);
if (strstr(style_ctx, ((struct header_element_data *)data)->name)){ char *style_ctx = gtk_style_context_to_string(style_context, GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE);
((struct header_element_data *)data)->widget = widget; if (strstr(style_ctx, elem->name) != 0){
free(style_ctx); elem->widget = widget;
return; match = true;
} }
free(style_ctx); free(style_ctx);
} }
if (GTK_IS_CONTAINER(widget)) {
/* recursively traverse container */ /* recursively traverse container */
gtk_container_forall(GTK_CONTAINER(widget), &find_widget_by_name, data); if (!match && GTK_IS_CONTAINER(widget)){
gtk_container_forall(GTK_CONTAINER(widget), &gtk_fill_widget_from_name, data);
} }
} }
@ -1777,16 +1779,16 @@ find_widget_by_type(GtkWidget *widget, enum header_element type){
default:break; default:break;
} }
struct header_element_data data = {.name = name, .type = type, .widget = NULL}; struct header_element_data data = {0};
find_widget_by_name(widget, &data); data.name = name;
return data; data.type = type;
gtk_fill_widget_from_name(widget, &data);
return(data);
} }
static struct header_element_data static struct header_element_data
get_header_focus(const GtkHeaderBar *header_bar, const int x, const int y){ get_header_focus(const GtkHeaderBar *header_bar, int x, int y){
static const enum header_element elems[] = { static const enum header_element elems[] = { HEADER_TITLE, HEADER_MIN, HEADER_MAX, HEADER_CLOSE };
HEADER_TITLE, HEADER_MIN, HEADER_MAX, HEADER_CLOSE
};
struct header_element_data result = {0}; struct header_element_data result = {0};
for (size_t i = 0; i < ARRAY_LENGTH(elems); i += 1){ for (size_t i = 0; i < ARRAY_LENGTH(elems); i += 1){
@ -2467,7 +2469,7 @@ border_size_from_window_state(enum libdecor_window_state window_state){
} }
enum libdecor_resize_edge enum libdecor_resize_edge
component_edge(enum component_slot slot, int x, int y){ edge_from_pos(int x, int y){
static const enum libdecor_resize_edge box[9] = { static const enum libdecor_resize_edge box[9] = {
LIBDECOR_RESIZE_EDGE_TOP_LEFT , LIBDECOR_RESIZE_EDGE_TOP , LIBDECOR_RESIZE_EDGE_TOP_RIGHT , LIBDECOR_RESIZE_EDGE_TOP_LEFT , LIBDECOR_RESIZE_EDGE_TOP , LIBDECOR_RESIZE_EDGE_TOP_RIGHT ,
LIBDECOR_RESIZE_EDGE_LEFT, LIBDECOR_RESIZE_EDGE_NONE , LIBDECOR_RESIZE_EDGE_RIGHT , LIBDECOR_RESIZE_EDGE_LEFT, LIBDECOR_RESIZE_EDGE_NONE , LIBDECOR_RESIZE_EDGE_RIGHT ,
@ -2475,20 +2477,15 @@ component_edge(enum component_slot slot, int x, int y){
}; };
enum libdecor_resize_edge result = 0; enum libdecor_resize_edge result = 0;
struct buffer *buffer = 0; struct buffer *buffer = ctx.component_slot[COMPONENT_SLOT_SHADOW].buffer;
if (slot < COMPONENT_SLOT_COUNT){
buffer = ctx.component_slot[slot].buffer;
}
if (buffer != 0){ if (buffer != 0){
int w = buffer->width; int w = buffer->width;
int h = buffer->height; int h = buffer->height;
int top = (y < 2*SHADOW_MARGIN); int top = (y < 2*SHADOW_MARGIN);
int bottom = (!top && y > (w - 2*SHADOW_MARGIN)); int bottom = (!top && y > (h - 2*SHADOW_MARGIN));
int left = (x < 2*SHADOW_MARGIN); int left = (x < 2*SHADOW_MARGIN);
int right = (!left && x > (h - 2*SHADOW_MARGIN)); int right = (!left && x > (w - 2*SHADOW_MARGIN));
int i = 4 + 3*(bottom - top) + (right - left); int i = 4 + 3*(bottom - top) + (right - left);
result = box[i]; result = box[i];
@ -2499,41 +2496,35 @@ component_edge(enum component_slot slot, int x, int y){
static bool static bool
update_local_cursor(struct seat *seat){ update_local_cursor(struct seat *seat){
bool cursor_updated = false;
seat->current_cursor = seat->cursor_left_ptr;
if (own_proxy(seat->pointer_focus)){
if (ctx.active != 0){
if (seat->cursor_theme == 0){ if (seat->cursor_theme == 0){
struct wl_cursor_theme *theme = wl_cursor_theme_load(ctx.cursor_theme_name, ctx.cursor_size, ctx.wl_shm); struct wl_cursor_theme *theme = wl_cursor_theme_load(ctx.cursor_theme_name, ctx.cursor_size, ctx.wl_shm);
if (theme != 0){ if (theme != 0){
seat->cursor_theme = theme; seat->cursor_theme = theme;
for (unsigned int i = 0; i < ARRAY_LENGTH(cursor_names); i += 1){ for (unsigned int i = 0; i < ARRAY_LENGTH(cursor_names); i += 1){
seat->cursors[i] = wl_cursor_theme_get_cursor(theme, cursor_names[i]); seat->cursors[i] = wl_cursor_theme_get_cursor(theme, cursor_names[i]);
} }
seat->cursor_left_ptr = wl_cursor_theme_get_cursor(seat->cursor_theme, "left_ptr"); seat->cursor_left_ptr = wl_cursor_theme_get_cursor(seat->cursor_theme, "left_ptr");
seat->current_cursor = seat->cursor_left_ptr;
cursor_updated = true;
} }
} }
struct wl_cursor *wl_cursor = seat->cursor_left_ptr; struct wl_cursor *wl_cursor = seat->cursor_left_ptr;
if (own_proxy(seat->pointer_focus)){
if (ctx.active != 0){
if (ctx.active == COMPONENT_SLOT_SHADOW && if (ctx.active == COMPONENT_SLOT_SHADOW &&
(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
enum libdecor_resize_edge edge = component_edge(COMPONENT_SLOT_SHADOW, seat->pointer_x, seat->pointer_y); enum libdecor_resize_edge edge = edge_from_pos(seat->pointer_x, seat->pointer_y);
if (edge != LIBDECOR_RESIZE_EDGE_NONE){ if (edge != LIBDECOR_RESIZE_EDGE_NONE){
wl_cursor = seat->cursors[edge - 1]; wl_cursor = seat->cursors[edge - 1];
} }
} }
}
}
bool cursor_updated = false;
if (seat->current_cursor != wl_cursor) { if (seat->current_cursor != wl_cursor) {
seat->current_cursor = wl_cursor; seat->current_cursor = wl_cursor;
cursor_updated = true; cursor_updated = true;
} }
}
}
return(cursor_updated); return(cursor_updated);
} }

View File

@ -146,7 +146,6 @@ enum titlebar_gesture_state {
struct header_element_data { struct header_element_data {
const char *name; const char *name;
enum header_element type; enum header_element type;
/* pointer to button or NULL if not found*/
GtkWidget *widget; GtkWidget *widget;
GtkStateFlags state; GtkStateFlags state;
}; };
@ -312,9 +311,9 @@ static void draw_border_component(struct border_component *border_component);
static bool own_proxy(void *proxy); static bool own_proxy(void *proxy);
static enum component_slot component_slot_from_wl_surface(const struct wl_surface *surface); 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, const int x, const int y); static struct header_element_data get_header_focus(const GtkHeaderBar *header_bar, int x, int y);
static void draw_title_bar(void); static void draw_title_bar(void);
enum libdecor_resize_edge component_edge(const enum component_slot slot, const int pointer_x, const int pointer_y); static enum libdecor_resize_edge edge_from_pos(int x, int y);
static void toggle_maximized(void); static void toggle_maximized(void);
static void update_touch_focus(struct seat *seat, wl_fixed_t x, wl_fixed_t y); static void update_touch_focus(struct seat *seat, wl_fixed_t x, wl_fixed_t y);