What do we really need from the gtk layer if we don't kick the can down the road?

main
Allen Webster 2026-03-05 16:55:06 -08:00
parent 1acd348886
commit d7770effea
2 changed files with 107 additions and 189 deletions

View File

@ -67,14 +67,14 @@ GL_FUNCS_XLIST(X)
static Ctx ctx = {0};
static void
shm_format(void *udata, struct wl_shm *wl_shm, uint32_t format){}
shm_format(void *udata, struct wl_shm *wl_shm, CSD_U32 format){}
static const struct wl_shm_listener shm_listener = {
shm_format
};
static void
xdg_wm_base_ping(void *udata, struct xdg_wm_base *xdg_wm_base, uint32_t serial){
xdg_wm_base_ping(void *udata, struct xdg_wm_base *xdg_wm_base, CSD_U32 serial){
xdg_wm_base_pong(xdg_wm_base, serial);
}
@ -83,169 +83,78 @@ static const struct xdg_wm_base_listener xdg_wm_base_listener = {
};
static void
pointer_enter(void *udata, struct wl_pointer *wl_pointer, uint32_t serial,
pointer_enter(void *udata, struct wl_pointer *wl_pointer, CSD_U32 serial,
struct wl_surface *surface, wl_fixed_t fx, wl_fixed_t fy){
CSD_Window *window = &ctx.window;
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
int32_t x = wl_fixed_to_int(fx);
int32_t y = wl_fixed_to_int(fy);
CSD_S32 surface_off[2] = {0};
if (surface == window->main_wl_surface){
printf("pointer_enter (main) %d,%d\n", x, y);
// surface_off = {0,0}
}
else if (surface == gtk_window->titlebar.wl_surface){
x += gtk_window->titlebar.p[0];
y += gtk_window->titlebar.p[1];
printf("pointer_enter (titlebar) %d,%d\n", x, y);
memcpy(surface_off, gtk_window->titlebar.p, sizeof(surface_off));
}
else if (surface == gtk_window->shadow.wl_surface){
x += gtk_window->shadow.p[0];
y += gtk_window->shadow.p[1];
printf("pointer_enter (shadow) %d,%d\n", x, y);
memcpy(surface_off, gtk_window->shadow.p, sizeof(surface_off));
}
else{
printf("pointer_enter (unidentified) %d,%d\n", x, y);
}
window->serial = serial;
ctx.hover_surface = surface;
ctx.hover_p[0] = x;
ctx.hover_p[1] = y;
#if 0
if (csd_gtk_pointer_enter(gtk_window, serial, surface, fx, fy)){
// handled by gtk
}
else if (surface == ctx.main_wl_surface){
int32_t x = wl_fixed_to_int(fx);
int32_t y = wl_fixed_to_int(fy);
// my event
}
else{
// unknown surface
}
ctx.hover_surface = surface;
#endif
CSD_Seat *seat = &ctx.seat;
seat->hover_surface = surface;
seat->hover_p[0] = surface_off[0] + wl_fixed_to_int(fx);
seat->hover_p[1] = surface_off[1] + wl_fixed_to_int(fy);
seat->serial = serial;
}
static void
pointer_leave(void *udata, struct wl_pointer *wl_pointer, uint32_t serial,
struct wl_surface *surface){
CSD_Window *window = &ctx.window;
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
if (surface == window->main_wl_surface){
printf("pointer_leave (main)\n");
}
else if (surface == gtk_window->titlebar.wl_surface){
printf("pointer_leave (titlebar)\n");
}
else if (surface == gtk_window->shadow.wl_surface){
printf("pointer_leave (shadow)\n");
}
else{
printf("pointer_leave (unidentified)\n");
}
ctx.hover_surface = 0;
#if 0
if (csd_gtk_pointer_leave(gtk_window, serial, surface)){
// handled by gtk
}
else if (surface == ctx.main_wl_surface){
int32_t x = wl_fixed_to_int(fx);
int32_t y = wl_fixed_to_int(fy);
// my event
}
else{
// unknown
}
#endif
pointer_leave(void *udata, struct wl_pointer *wl_pointer,
CSD_U32 serial, struct wl_surface *surface){
CSD_Seat *seat = &ctx.seat;
seat->hover_surface = 0;
seat->serial = serial;
}
static void
pointer_motion(void *udata, struct wl_pointer *wl_pointer, uint32_t time,
wl_fixed_t fx, wl_fixed_t fy){
pointer_motion(void *udata, struct wl_pointer *wl_pointer,
CSD_U32 time, wl_fixed_t fx, wl_fixed_t fy){
CSD_Window *window = &ctx.window;
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
int32_t x = wl_fixed_to_int(fx);
int32_t y = wl_fixed_to_int(fy);
if (ctx.hover_surface == window->main_wl_surface){
printf("pointer_motion (main) %d,%d\n", x, y);
}
else if (ctx.hover_surface == gtk_window->titlebar.wl_surface){
x += gtk_window->titlebar.p[0];
y += gtk_window->titlebar.p[1];
printf("pointer_motion (titlebar) %d,%d\n", x, y);
}
else if (ctx.hover_surface == gtk_window->shadow.wl_surface){
x += gtk_window->shadow.p[0];
y += gtk_window->shadow.p[1];
printf("pointer_motion (shadow) %d,%d\n", x, y);
}
else{
printf("pointer_motion (unidentified) %d,%d\n", x, y);
}
ctx.hover_p[0] = x;
ctx.hover_p[1] = y;
CSD_Seat *seat = &ctx.seat;
#if 0
if (csd_gtk_pointer_motion(&ctx.gtk_window, ctx.hover_surface,
time, fx, fy)){
// handled by gtk
CSD_S32 surface_off[2] = {0};
if (seat->hover_surface == window->main_wl_surface){
// surface_off = {0,0}
}
else if (surface == ctx.main_wl_surface){
int32_t x = wl_fixed_to_int(fx);
int32_t y = wl_fixed_to_int(fy);
// my event
else if (seat->hover_surface == gtk_window->titlebar.wl_surface){
memcpy(surface_off, gtk_window->titlebar.p, sizeof(surface_off));
}
else{
// unknown
else if (seat->hover_surface == gtk_window->shadow.wl_surface){
memcpy(surface_off, gtk_window->shadow.p, sizeof(surface_off));
}
#endif
seat->hover_p[0] = surface_off[0] + wl_fixed_to_int(fx);
seat->hover_p[1] = surface_off[1] + wl_fixed_to_int(fy);
}
static void
pointer_button(void *udata, struct wl_pointer *wl_pointer, uint32_t serial,
uint32_t time, uint32_t button, uint32_t state){
pointer_button(void *udata, struct wl_pointer *wl_pointer,
CSD_U32 serial, CSD_U32 time, CSD_U32 button, CSD_U32 state){
CSD_Seat *seat = &ctx.seat;
CSD_Window *window = &ctx.window;
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
char *state_str = (state == 1?"press":"release");
if (button == BTN_LEFT){
printf("pointer_button (left) %s\n", state_str);
{
ctx.has_event = 1;
ctx.event_button = button;
ctx.event_button_state = state;
}
else if (button == BTN_RIGHT){
printf("pointer_button (right) %s\n", state_str);
}
else if (button == BTN_MIDDLE){
printf("pointer_button (middle) %s\n", state_str);
}
else{
printf("pointer_button (unidentified) %s\n", state_str);
}
if (state){
gtk_window->button = button;
}
window->serial = serial;
#if 0
if (csd_gtk_pointer_button(&ctx.gtk_window, serial, time, button, state)){
// handled by gtk
}
else if (surface == ctx.main_wl_surface){
int32_t x = wl_fixed_to_int(fx);
int32_t y = wl_fixed_to_int(fy);
// my event
}
else{
// unknown
}
#endif
seat->serial = serial;
}
static void
pointer_axis(void *udata, struct wl_pointer *wl_pointer,
uint32_t time, uint32_t axis, wl_fixed_t fv){
CSD_U32 time, CSD_U32 axis, wl_fixed_t fv){
int v = wl_fixed_to_int(fv);
printf("pointer_axis %u,%d\n", axis, v);
}
static const struct wl_pointer_listener pointer_listener = {
@ -257,14 +166,15 @@ static const struct wl_pointer_listener pointer_listener = {
};
static void
seat_capabilities(void *udata, struct wl_seat *wl_seat, uint32_t capabilities){
if ((capabilities & WL_SEAT_CAPABILITY_POINTER) && ctx.wl_pointer == 0){
ctx.wl_pointer = wl_seat_get_pointer(ctx.wl_seat);
wl_pointer_add_listener(ctx.wl_pointer, &pointer_listener, 0);
seat_capabilities(void *udata, struct wl_seat *wl_seat, CSD_U32 capabilities){
CSD_Seat *seat = &ctx.seat;
if ((capabilities & WL_SEAT_CAPABILITY_POINTER) && seat->wl_pointer == 0){
seat->wl_pointer = wl_seat_get_pointer(seat->wl_seat);
wl_pointer_add_listener(seat->wl_pointer, &pointer_listener, 0);
}
else if (!(capabilities & WL_SEAT_CAPABILITY_POINTER) && ctx.wl_pointer != 0){
wl_pointer_release(ctx.wl_pointer);
ctx.wl_pointer = 0;
else if (!(capabilities & WL_SEAT_CAPABILITY_POINTER) && seat->wl_pointer != 0){
wl_pointer_release(seat->wl_pointer);
seat->wl_pointer = 0;
}
}
@ -278,8 +188,7 @@ static const struct wl_seat_listener seat_listener = {
static void
registry_global(void *udata, struct wl_registry *wl_registry,
uint32_t name, const char *interface,
uint32_t version){
CSD_U32 name, const char *interface, CSD_U32 version){
if (strcmp(interface, "wl_compositor") == 0){
ctx.wl_compositor = (struct wl_compositor*)
wl_registry_bind(wl_registry, name, &wl_compositor_interface,
@ -306,9 +215,12 @@ registry_global(void *udata, struct wl_registry *wl_registry,
CSD_Min(version, 2));
}
else if (strcmp(interface, "wl_seat") == 0){
ctx.wl_seat = wl_registry_bind(ctx.wl_registry, name, &wl_seat_interface, 3);
wl_seat_add_listener(ctx.wl_seat, &seat_listener, 0);
ctx.cursor_surface = wl_compositor_create_surface(ctx.wl_compositor);
CSD_Seat *seat = &ctx.seat;
if (seat->wl_seat == 0){
seat->wl_seat = wl_registry_bind(ctx.wl_registry, name, &wl_seat_interface, 3);
wl_seat_add_listener(seat->wl_seat, &seat_listener, 0);
seat->cursor_surface = wl_compositor_create_surface(ctx.wl_compositor);
}
}
}
@ -617,9 +529,12 @@ int main(){
window->dim[1] + window->csd_dim[1]);
wl_egl_window_resize(ctx.main_wl_egl_window,
window->dim[0], window->dim[1], 0, 0);
}
/* frame update and render */
ctx.cursor_shape = CSD_CursorShape_Pointer;
/* frame update and render */
{
CSD_Seat *seat = &ctx.seat;
seat->cursor_shape = CSD_CursorShape_Pointer;
csd_gtk_update_and_render();
}
@ -644,17 +559,18 @@ int main(){
/* commit new cursor */
{
CSD_Seat *seat = &ctx.seat;
CSD_Window *window = &ctx.window;
struct wl_cursor *cursor = ctx.wl_cursors[ctx.cursor_shape];
struct wl_cursor *cursor = ctx.wl_cursors[seat->cursor_shape];
if (cursor != 0){
struct wl_cursor_image *cursor_image = cursor->images[0];
struct wl_buffer *cursor_buffer = wl_cursor_image_get_buffer(cursor_image);
wl_surface_set_buffer_scale(ctx.cursor_surface, 1);
wl_surface_attach(ctx.cursor_surface, cursor_buffer, 0, 0);
wl_surface_damage_buffer(ctx.cursor_surface, 0, 0,
wl_surface_set_buffer_scale(seat->cursor_surface, 1);
wl_surface_attach(seat->cursor_surface, cursor_buffer, 0, 0);
wl_surface_damage_buffer(seat->cursor_surface, 0, 0,
cursor_image->width, cursor_image->height);
wl_surface_commit(ctx.cursor_surface);
wl_pointer_set_cursor(ctx.wl_pointer, window->serial, ctx.cursor_surface,
wl_surface_commit(seat->cursor_surface);
wl_pointer_set_cursor(seat->wl_pointer, seat->serial, seat->cursor_surface,
cursor_image->hotspot_x, cursor_image->hotspot_y);
}
}
@ -1112,6 +1028,7 @@ csd_gtk__widget_from_name(GtkWidget *root, char *name){
static void
csd_gtk_update_and_render(void){
CSD_Seat *seat = &ctx.seat;
CSD_Window *window = &ctx.window;
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
@ -1128,20 +1045,22 @@ csd_gtk_update_and_render(void){
XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT,
};
int l = (ctx.hover_p[0] < 0);
int r = (!l && ctx.hover_p[0] >= window->dim[0]);
int t = (ctx.hover_p[1] < -window->csd_frame.border[1][0]);
int b = (!t && ctx.hover_p[1] >= window->dim[1]);
int loc = 3*(b - t) + (r - l);
ctx.cursor_shape = cursor_box[4 + loc];
if (gtk_window->button == BTN_LEFT){
gtk_window->button = 0;
CSD_S32 l = (seat->hover_p[0] < 0);
CSD_S32 r = (!l && seat->hover_p[0] >= window->dim[0]);
CSD_S32 t = (seat->hover_p[1] < -window->csd_frame.border[1][0]);
CSD_S32 b = (!t && seat->hover_p[1] >= window->dim[1]);
CSD_S32 loc = 3*(b - t) + (r - l);
seat->cursor_shape = cursor_box[4 + loc];
if (ctx.has_event &&
ctx.event_button == BTN_LEFT &&
ctx.event_button_state == 1){
ctx.has_event = 0;
if (loc != 0){
xdg_toplevel_resize(window->main_xdg_toplevel, ctx.wl_seat,
window->serial, xedge_box[4 + loc]);
xdg_toplevel_resize(window->main_xdg_toplevel, seat->wl_seat,
seat->serial, xedge_box[4 + loc]);
}
else if (ctx.hover_p[1] < 0){
xdg_toplevel_move(window->main_xdg_toplevel, ctx.wl_seat, window->serial);
else if (seat->hover_p[1] < 0){
xdg_toplevel_move(window->main_xdg_toplevel, seat->wl_seat, seat->serial);
}
}
}
@ -1149,7 +1068,7 @@ csd_gtk_update_and_render(void){
{
CSD_SubSurface *subsurface = &gtk_window->shadow;
int32_t shadow_dim[2];
CSD_S32 shadow_dim[2];
shadow_dim[0] = window->dim[0] + 2*SHADOW_MARGIN;
shadow_dim[1] = (window->dim[1] + 2*SHADOW_MARGIN +
window->csd_frame.border[1][0]);
@ -1192,7 +1111,7 @@ csd_gtk_update_and_render(void){
{
CSD_SubSurface *subsurface = &gtk_window->titlebar;
int32_t title_dim[2];
CSD_S32 title_dim[2];
title_dim[0] = window->dim[0];
title_dim[1] = window->csd_frame.border[1][0];
@ -1227,7 +1146,7 @@ csd_gtk_update_and_render(void){
}
{
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, title_dim[0]);
CSD_S32 stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, title_dim[0]);
cairo_surface_t *cr_surface =
cairo_image_surface_create_for_data(subsurface->data, CAIRO_FORMAT_ARGB32,
title_dim[0], title_dim[1], stride);
@ -1263,7 +1182,7 @@ csd_gtk_update_and_render(void){
}
/* buttons */
uint32_t buttons[3] = {0};
CSD_U32 buttons[3] = {0};
int button_count = 0;
if (window->control_flags & CSD_WindowControlFlag_Min){
buttons[button_count] = 0;

View File

@ -86,7 +86,7 @@ typedef struct CSD_Config{
} CSD_Config;
typedef struct CSD_Frame{
CSD_S32 border[2][2]; // [0][]:x [1][]:y [][0]:min [][1]:max
CSD_S32 border[2][2];
CSD_S32 minbox[2];
} CSD_Frame;
@ -111,7 +111,6 @@ typedef struct CSD_Window{
CSD_Config config;
CSD_Config config_staged;
CSD_U32 serial;
CSD_Frame csd_frame;
CSD_S32 csd_dim[2];
@ -120,6 +119,18 @@ typedef struct CSD_Window{
CSD_S32 dim[2];
} CSD_Window;
typedef struct CSD_Seat{
struct wl_seat *wl_seat;
struct wl_pointer *wl_pointer;
struct wl_surface *cursor_surface;
CSD_CursorShape cursor_shape;
struct wl_surface *hover_surface;
CSD_S32 hover_p[2];
CSD_U32 serial;
} CSD_Seat;
/* csd helpers */
static CSD_SubSurface csd_subsurface_new(void);
@ -156,7 +167,6 @@ typedef struct CSD_GTK_Ctx{
} CSD_GTK_Ctx;
typedef struct CSD_GTK_Window{
CSD_U32 button;
CSD_S32 double_click_time_ms;
CSD_SubSurface titlebar;
@ -176,14 +186,6 @@ 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);
#if 0
static CSD_B32 csd_gtk_pointer_enter(CSD_GTK_Window *gtk_window, uint32_t serial, struct wl_surface *surface, wl_fixed_t fx, wl_fixed_t fy);
static CSD_B32 csd_gtk_pointer_leave(CSD_GTK_Window *gtk_window, uint32_t serial, struct wl_surface *surface);
static CSD_B32 csd_gtk_pointer_motion(CSD_GTK_Window *gtk_window, uint32_t time, wl_fixed_t fx, wl_fixed_t fy);
static CSD_B32 csd_gtk_pointer_button(CSD_GTK_Window *gtk_window, uint32_t serial, uint32_t time, uint32_t button, uint32_t state);
#endif
/* csd gtk cairo shadow rendering */
@ -196,9 +198,13 @@ static void csd_gtk_render_shadow(cairo_t *cr, cairo_surface_t *surface,
/* example */
typedef struct Ctx{
/* "application variables" */
/* the rest */
CSD_B32 close_signal;
CSD_B32 has_event;
CSD_U32 event_button;
CSD_U32 event_button_state;
/* globals: desktop settings */
CSD_ColorScheme color_scheme;
CSD_CursorTheme cursor_theme;
@ -222,15 +228,8 @@ typedef struct Ctx{
/* globals: gtk */
CSD_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;
CSD_S32 hover_p[2];
CSD_CursorShape cursor_shape;
/* per-seat */
CSD_Seat seat;
/* per-window: egl */
struct wl_egl_window *main_wl_egl_window;