[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
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;
if (seat->cursor_surface == 0){
seat->cursor_surface = wl_compositor_create_surface(ctx.wl_compositor);
}
seat->pointer_x = wl_fixed_to_int(surface_x);
seat->pointer_y = wl_fixed_to_int(surface_y);
seat->pointer_x = wl_fixed_to_int(x);
seat->pointer_y = wl_fixed_to_int(y);
seat->serial = serial;
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;
}
new_focus = get_header_focus(GTK_HEADER_BAR(ctx.header),
seat->pointer_x, seat->pointer_y);
new_focus = get_header_focus(GTK_HEADER_BAR(ctx.header), seat->pointer_x, seat->pointer_y);
/* 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.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)){
switch (ctx.active){
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 &&
(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
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){
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 &&
(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
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);
seat->wl_seat = wl_registry_bind(ctx.wl_registry, name, &wl_seat_interface, 3);
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"
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)){
char *style_ctx = gtk_style_context_to_string(gtk_widget_get_style_context(widget),
GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE);
if (strstr(style_ctx, ((struct header_element_data *)data)->name)){
((struct header_element_data *)data)->widget = widget;
free(style_ctx);
return;
struct header_element_data *elem = data;
GtkStyleContext *style_context = gtk_widget_get_style_context(widget);
char *style_ctx = gtk_style_context_to_string(style_context, GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE);
if (strstr(style_ctx, elem->name) != 0){
elem->widget = widget;
match = true;
}
free(style_ctx);
}
if (GTK_IS_CONTAINER(widget)) {
/* 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;
}
struct header_element_data data = {.name = name, .type = type, .widget = NULL};
find_widget_by_name(widget, &data);
return data;
struct header_element_data data = {0};
data.name = name;
data.type = type;
gtk_fill_widget_from_name(widget, &data);
return(data);
}
static struct header_element_data
get_header_focus(const GtkHeaderBar *header_bar, const int x, const int y){
static const enum header_element elems[] = {
HEADER_TITLE, HEADER_MIN, HEADER_MAX, HEADER_CLOSE
};
get_header_focus(const GtkHeaderBar *header_bar, int x, int y){
static const enum header_element elems[] = { HEADER_TITLE, HEADER_MIN, HEADER_MAX, HEADER_CLOSE };
struct header_element_data result = {0};
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
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] = {
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 ,
@ -2475,20 +2477,15 @@ component_edge(enum component_slot slot, int x, int y){
};
enum libdecor_resize_edge result = 0;
struct buffer *buffer = 0;
if (slot < COMPONENT_SLOT_COUNT){
buffer = ctx.component_slot[slot].buffer;
}
struct buffer *buffer = ctx.component_slot[COMPONENT_SLOT_SHADOW].buffer;
if (buffer != 0){
int w = buffer->width;
int h = buffer->height;
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 right = (!left && x > (h - 2*SHADOW_MARGIN));
int right = (!left && x > (w - 2*SHADOW_MARGIN));
int i = 4 + 3*(bottom - top) + (right - left);
result = box[i];
@ -2499,41 +2496,35 @@ component_edge(enum component_slot slot, int x, int y){
static bool
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){
struct wl_cursor_theme *theme = wl_cursor_theme_load(ctx.cursor_theme_name, ctx.cursor_size, ctx.wl_shm);
if (theme != 0){
seat->cursor_theme = theme;
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->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;
if (own_proxy(seat->pointer_focus)){
if (ctx.active != 0){
if (ctx.active == COMPONENT_SLOT_SHADOW &&
(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){
wl_cursor = seat->cursors[edge - 1];
}
}
}
}
bool cursor_updated = false;
if (seat->current_cursor != wl_cursor) {
seat->current_cursor = wl_cursor;
cursor_updated = true;
}
}
}
return(cursor_updated);
}

View File

@ -146,7 +146,6 @@ enum titlebar_gesture_state {
struct header_element_data {
const char *name;
enum header_element type;
/* pointer to button or NULL if not found*/
GtkWidget *widget;
GtkStateFlags state;
};
@ -312,9 +311,9 @@ static void draw_border_component(struct border_component *border_component);
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, 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);
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 update_touch_focus(struct seat *seat, wl_fixed_t x, wl_fixed_t y);