[digesting_libdecor] simplify header focus and drag focus

main
Allen Webster 2026-03-02 12:12:21 -08:00
parent 2770ddc39b
commit 107aa41329
2 changed files with 43 additions and 59 deletions

View File

@ -344,6 +344,8 @@ xdg_toplevel_decoration_configure(void *data, struct zxdg_toplevel_decoration_v1
const struct zxdg_toplevel_decoration_v1_listener const struct zxdg_toplevel_decoration_v1_listener
xdg_toplevel_decoration_listener = { xdg_toplevel_decoration_configure, }; xdg_toplevel_decoration_listener = { xdg_toplevel_decoration_configure, };
static GtkWidget* find_widget_by_type(GtkWidget *root, enum header_element type);
int main(){ int main(){
/* get desktop settings */ /* get desktop settings */
ctx.color_scheme = desktop_settings_get_color_scheme(); ctx.color_scheme = desktop_settings_get_color_scheme();
@ -663,7 +665,6 @@ int main(){
ctx.pointer_leave = 0; ctx.pointer_leave = 0;
ctx.titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT; ctx.titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT;
ctx.titlebar_gesture.first_pressed_button = 0; ctx.titlebar_gesture.first_pressed_button = 0;
ctx.hdr_focus.widget = 0; ctx.hdr_focus.widget = 0;
ctx.hdr_focus.type = HEADER_NONE; ctx.hdr_focus.type = HEADER_NONE;
draw_decoration(); draw_decoration();
@ -684,27 +685,44 @@ int main(){
if (!GTK_IS_WIDGET(ctx.header) || ctx.active != COMPONENT_SLOT_HEADER){ if (!GTK_IS_WIDGET(ctx.header) || ctx.active != COMPONENT_SLOT_HEADER){
ctx.hdr_focus.type = HEADER_NONE; ctx.hdr_focus.type = HEADER_NONE;
} }
struct header_element_data new_focus =
get_header_focus(GTK_HEADER_BAR(ctx.header), ctx.seat->pointer_x, ctx.seat->pointer_y);
struct header_element_data new_focus = {0};
{
int x = ctx.seat->pointer_x;
int y = ctx.seat->pointer_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){
GtkWidget *widget = find_widget_by_type(GTK_WIDGET(ctx.header), elems[i]);
if (widget != 0){
GtkAllocation allocation;
gtk_widget_get_allocation(GTK_WIDGET(widget), &allocation);
if (allocation.x <= x && x < allocation.x + allocation.width &&
allocation.y <= y && y < allocation.y + allocation.height){
new_focus.type = elems[i];
new_focus.widget = widget;
break;
}
}
}
}
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_state = 0; ctx.hdr_focus_is_active = 0;
} }
ctx.hdr_state |= GTK_STATE_FLAG_PRELIGHT;
draw_title_bar();
wl_surface_commit(ctx.wl_surface);
if (ctx.titlebar_gesture.state == TITLEBAR_GESTURE_STATE_BUTTON_PRESSED){ if (ctx.titlebar_gesture.state == TITLEBAR_GESTURE_STATE_BUTTON_PRESSED){
if (ctx.titlebar_gesture.first_pressed_button == BTN_LEFT){ if (ctx.titlebar_gesture.first_pressed_button == BTN_LEFT){
int xd = ABS(ctx.seat->pointer_x - ctx.titlebar_gesture.pressed_x); if (ctx.seat->pointer_x != ctx.titlebar_gesture.pressed_x ||
int yd = ABS(ctx.seat->pointer_y - ctx.titlebar_gesture.pressed_y); ctx.seat->pointer_y != ctx.titlebar_gesture.pressed_y){
if (xd > ctx.drag_threshold || yd > ctx.drag_threshold){
xdg_toplevel_move(ctx.xdg_toplevel, ctx.seat->wl_seat, ctx.titlebar_gesture.serial); xdg_toplevel_move(ctx.xdg_toplevel, ctx.seat->wl_seat, ctx.titlebar_gesture.serial);
} }
} }
} }
draw_title_bar();
wl_surface_commit(ctx.wl_surface);
} }
if (ctx.pointer_button){ if (ctx.pointer_button){
@ -764,7 +782,7 @@ int main(){
case HEADER_MIN: case HEADER_MIN:
case HEADER_MAX: case HEADER_MAX:
case HEADER_CLOSE: { case HEADER_CLOSE: {
ctx.hdr_state |= GTK_STATE_FLAG_ACTIVE; ctx.hdr_focus_is_active = 1;
draw_title_bar(); draw_title_bar();
wl_surface_commit(ctx.wl_surface); wl_surface_commit(ctx.wl_surface);
}break; }break;
@ -782,7 +800,7 @@ int main(){
else{ else{
ctx.titlebar_gesture.button_pressed_count -= 1; ctx.titlebar_gesture.button_pressed_count -= 1;
if (ctx.titlebar_gesture.button_pressed_count == 0) { if (ctx.titlebar_gesture.button_pressed_count == 0){
ctx.titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT; ctx.titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT;
if (ctx.titlebar_gesture.first_pressed_button == ctx.pointer_button_button && if (ctx.titlebar_gesture.first_pressed_button == ctx.pointer_button_button &&
ctx.pointer_button_button == BTN_LEFT){ ctx.pointer_button_button == BTN_LEFT){
@ -809,22 +827,18 @@ int main(){
default: break; default: break;
} }
ctx.hdr_state &= ~GTK_STATE_FLAG_ACTIVE; ctx.hdr_focus_is_active = 0;
if (GTK_IS_WIDGET(ctx.header)){
draw_title_bar();
wl_surface_commit(ctx.wl_surface);
}
} }
} }
else{ else{
ctx.hdr_state &= ~GTK_STATE_FLAG_ACTIVE; ctx.hdr_focus_is_active = 0;
}
if (GTK_IS_WIDGET(ctx.header)) { if (GTK_IS_WIDGET(ctx.header)) {
draw_title_bar(); draw_title_bar();
wl_surface_commit(ctx.wl_surface); wl_surface_commit(ctx.wl_surface);
} }
} }
}
}break; }break;
case TITLEBAR_GESTURE_STATE_CONSUMED: case TITLEBAR_GESTURE_STATE_CONSUMED:
@ -852,6 +866,10 @@ int main(){
if (ctx.has_cached_config){ if (ctx.has_cached_config){
ctx.has_cached_config = 0; ctx.has_cached_config = 0;
if (ctx.cached_config.initialized){
ctx.frame_window_state = ctx.cached_config.window_state;
}
if (ctx.cached_config.initialized && if (ctx.cached_config.initialized &&
ctx.cached_config.window_width != 0 && ctx.cached_config.window_width != 0 &&
ctx.cached_config.window_height != 0){ ctx.cached_config.window_height != 0){
@ -859,7 +877,6 @@ int main(){
int h = ctx.cached_config.window_height; int h = ctx.cached_config.window_height;
if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){
ctx.frame_window_state = ctx.cached_config.window_state;
Sides2D border_size = border_size_from_window_state(ctx.cached_config.window_state); Sides2D border_size = border_size_from_window_state(ctx.cached_config.window_state);
w -= border_size.x[0] + border_size.x[1]; w -= border_size.x[0] + border_size.x[1];
h -= border_size.y[0] + border_size.y[1]; h -= border_size.y[0] + border_size.y[1];
@ -884,9 +901,6 @@ int main(){
ctx.h = h; ctx.h = h;
} }
if (ctx.cached_config.initialized){
ctx.frame_window_state = ctx.cached_config.window_state;
}
frame_commit(); frame_commit();
xdg_surface_ack_configure(ctx.xdg_surface, ctx.cached_config.serial); xdg_surface_ack_configure(ctx.xdg_surface, ctx.cached_config.serial);
} }
@ -1426,28 +1440,6 @@ find_widget_by_type(GtkWidget *root, enum header_element type){
return(vars.widget); return(vars.widget);
} }
static struct header_element_data
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){
GtkWidget *widget = find_widget_by_type(GTK_WIDGET(header_bar), elems[i]);
if (widget != 0){
GtkAllocation allocation;
gtk_widget_get_allocation(GTK_WIDGET(widget), &allocation);
if (allocation.x <= x && x < allocation.x + allocation.width &&
allocation.y <= y && y < allocation.y + allocation.height){
result.type = elems[i];
result.widget = widget;
break;
}
}
}
return(result);
}
static bool static bool
own_proxy(void *proxy){ own_proxy(void *proxy){
bool result = false; bool result = false;
@ -1522,7 +1514,6 @@ ensure_title_bar_surfaces(void){
g_object_get(gtk_widget_get_settings(ctx.window), g_object_get(gtk_widget_get_settings(ctx.window),
"gtk-double-click-time", &ctx.double_click_time_ms, "gtk-double-click-time", &ctx.double_click_time_ms,
"gtk-dnd-drag-threshold", &ctx.drag_threshold,
NULL); NULL);
g_object_set(ctx.header, g_object_set(ctx.header,
"title", ctx.title, "title", ctx.title,
@ -1606,7 +1597,7 @@ draw_header_button(cairo_t *cr, cairo_surface_t *surface,
} }
if (ctx.hdr_focus.widget == button){ if (ctx.hdr_focus.widget == button){
style_state |= GTK_STATE_FLAG_PRELIGHT; style_state |= GTK_STATE_FLAG_PRELIGHT;
if (ctx.hdr_state & GTK_STATE_FLAG_ACTIVE){ if (ctx.hdr_focus_is_active){
style_state |= GTK_STATE_FLAG_ACTIVE; style_state |= GTK_STATE_FLAG_ACTIVE;
} }
} }

View File

@ -240,12 +240,6 @@ struct seat{
struct wl_list link; struct wl_list link;
}; };
enum titlebar_gesture{
TITLEBAR_GESTURE_DOUBLE_CLICK,
TITLEBAR_GESTURE_MIDDLE_CLICK,
TITLEBAR_GESTURE_RIGHT_CLICK,
};
// libdecor.h // libdecor.h
void frame_commit(void); void frame_commit(void);
@ -315,7 +309,6 @@ typedef struct Ctx{
bool has_argb; bool has_argb;
int double_click_time_ms; int double_click_time_ms;
int drag_threshold;
cairo_surface_t *shadow_blur; cairo_surface_t *shadow_blur;
@ -373,7 +366,7 @@ typedef struct Ctx{
GtkWidget *window; GtkWidget *window;
GtkWidget *header; GtkWidget *header;
struct header_element_data hdr_focus; struct header_element_data hdr_focus;
GtkStateFlags hdr_state; bool hdr_focus_is_active;
struct { struct {
enum titlebar_gesture_state state; enum titlebar_gesture_state state;