[wayland_gtk_egl] sort out window specific fields (WIP), proper resize and move controls

main
Allen Webster 2026-03-05 13:05:03 -08:00
parent f56f60c2fb
commit 1acd348886
2 changed files with 262 additions and 156 deletions

View File

@ -85,72 +85,130 @@ static const struct xdg_wm_base_listener xdg_wm_base_listener = {
static void static void
pointer_enter(void *udata, struct wl_pointer *wl_pointer, uint32_t serial, pointer_enter(void *udata, struct wl_pointer *wl_pointer, uint32_t serial,
struct wl_surface *surface, wl_fixed_t fx, wl_fixed_t fy){ 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 x = wl_fixed_to_int(fx);
int32_t y = wl_fixed_to_int(fy); int32_t y = wl_fixed_to_int(fy);
if (surface == ctx.main_wl_surface){ if (surface == window->main_wl_surface){
printf("pointer_enter (main) %d,%d\n", x, y); printf("pointer_enter (main) %d,%d\n", x, y);
} }
else if (surface == ctx.gtk_window.titlebar.wl_surface){ else if (surface == gtk_window->titlebar.wl_surface){
x += ctx.gtk_window.titlebar.p[0]; x += gtk_window->titlebar.p[0];
y += ctx.gtk_window.titlebar.p[1]; y += gtk_window->titlebar.p[1];
printf("pointer_enter (titlebar) %d,%d\n", x, y); printf("pointer_enter (titlebar) %d,%d\n", x, y);
} }
else if (surface == ctx.gtk_window.shadow.wl_surface){ else if (surface == gtk_window->shadow.wl_surface){
x += ctx.gtk_window.shadow.p[0]; x += gtk_window->shadow.p[0];
y += ctx.gtk_window.shadow.p[1]; y += gtk_window->shadow.p[1];
printf("pointer_enter (shadow) %d,%d\n", x, y); printf("pointer_enter (shadow) %d,%d\n", x, y);
} }
else{ else{
printf("pointer_enter (unidentified) %d,%d\n", x, y); printf("pointer_enter (unidentified) %d,%d\n", x, y);
} }
ctx.serial = serial; window->serial = serial;
ctx.hover_surface = surface; 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
} }
static void static void
pointer_leave(void *udata, struct wl_pointer *wl_pointer, uint32_t serial, pointer_leave(void *udata, struct wl_pointer *wl_pointer, uint32_t serial,
struct wl_surface *surface){ struct wl_surface *surface){
if (surface == ctx.main_wl_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"); printf("pointer_leave (main)\n");
} }
else if (surface == ctx.gtk_window.titlebar.wl_surface){ else if (surface == gtk_window->titlebar.wl_surface){
printf("pointer_leave (titlebar)\n"); printf("pointer_leave (titlebar)\n");
} }
else if (surface == ctx.gtk_window.shadow.wl_surface){ else if (surface == gtk_window->shadow.wl_surface){
printf("pointer_leave (shadow)\n"); printf("pointer_leave (shadow)\n");
} }
else{ else{
printf("pointer_leave (unidentified)\n"); printf("pointer_leave (unidentified)\n");
} }
ctx.hover_surface = 0; 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
} }
static void static void
pointer_motion(void *udata, struct wl_pointer *wl_pointer, uint32_t time, pointer_motion(void *udata, struct wl_pointer *wl_pointer, uint32_t time,
wl_fixed_t fx, wl_fixed_t fy){ 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 x = wl_fixed_to_int(fx);
int32_t y = wl_fixed_to_int(fy); int32_t y = wl_fixed_to_int(fy);
if (ctx.hover_surface == ctx.main_wl_surface){ if (ctx.hover_surface == window->main_wl_surface){
printf("pointer_motion (main) %d,%d\n", x, y); printf("pointer_motion (main) %d,%d\n", x, y);
} }
else if (ctx.hover_surface == ctx.gtk_window.titlebar.wl_surface){ else if (ctx.hover_surface == gtk_window->titlebar.wl_surface){
x += ctx.gtk_window.titlebar.p[0]; x += gtk_window->titlebar.p[0];
y += ctx.gtk_window.titlebar.p[1]; y += gtk_window->titlebar.p[1];
printf("pointer_motion (titlebar) %d,%d\n", x, y); printf("pointer_motion (titlebar) %d,%d\n", x, y);
} }
else if (ctx.hover_surface == ctx.gtk_window.shadow.wl_surface){ else if (ctx.hover_surface == gtk_window->shadow.wl_surface){
x += ctx.gtk_window.shadow.p[0]; x += gtk_window->shadow.p[0];
y += ctx.gtk_window.shadow.p[1]; y += gtk_window->shadow.p[1];
printf("pointer_motion (shadow) %d,%d\n", x, y); printf("pointer_motion (shadow) %d,%d\n", x, y);
} }
else{ else{
printf("pointer_motion (unidentified) %d,%d\n", x, y); printf("pointer_motion (unidentified) %d,%d\n", x, y);
} }
ctx.hover_p[0] = x;
ctx.hover_p[1] = y;
#if 0
if (csd_gtk_pointer_motion(&ctx.gtk_window, ctx.hover_surface,
time, 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
}
#endif
} }
static void static void
pointer_button(void *udata, struct wl_pointer *wl_pointer, uint32_t serial, pointer_button(void *udata, struct wl_pointer *wl_pointer, uint32_t serial,
uint32_t time, uint32_t button, uint32_t state){ uint32_t time, uint32_t button, uint32_t state){
CSD_Window *window = &ctx.window;
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
char *state_str = (state == 1?"press":"release"); char *state_str = (state == 1?"press":"release");
if (button == BTN_LEFT){ if (button == BTN_LEFT){
printf("pointer_button (left) %s\n", state_str); printf("pointer_button (left) %s\n", state_str);
@ -165,9 +223,22 @@ pointer_button(void *udata, struct wl_pointer *wl_pointer, uint32_t serial,
printf("pointer_button (unidentified) %s\n", state_str); printf("pointer_button (unidentified) %s\n", state_str);
} }
if (state){ if (state){
ctx.gtk_window.button = button; gtk_window->button = button;
} }
ctx.serial = serial; 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
} }
static void static void
@ -253,7 +324,8 @@ static const struct wl_registry_listener registry_listener = {
static void static void
xdg_surface_configure(void *udata, struct xdg_surface *xdg_surface, xdg_surface_configure(void *udata, struct xdg_surface *xdg_surface,
uint32_t serial){ uint32_t serial){
ctx.config_staged.serial = serial; CSD_Window *window = &ctx.window;
window->config_staged.serial = serial;
} }
static const struct xdg_surface_listener xdg_surface_listener = { static const struct xdg_surface_listener xdg_surface_listener = {
@ -263,15 +335,16 @@ static const struct xdg_surface_listener xdg_surface_listener = {
static void static void
xdg_toplevel_configure(void *udata, struct xdg_toplevel *xdg_toplevel, xdg_toplevel_configure(void *udata, struct xdg_toplevel *xdg_toplevel,
int32_t width, int32_t height, struct wl_array *states){ int32_t width, int32_t height, struct wl_array *states){
CSD_Window *window = &ctx.window;
if (width != 0 && height != 0){ if (width != 0 && height != 0){
ctx.config_staged.dim[0] = width; window->config_staged.dim[0] = width;
ctx.config_staged.dim[1] = height; window->config_staged.dim[1] = height;
} }
else{ else{
ctx.config_staged.dim[0] = ctx.config.dim[0]; window->config_staged.dim[0] = window->config.dim[0];
ctx.config_staged.dim[1] = ctx.config.dim[1]; window->config_staged.dim[1] = window->config.dim[1];
} }
ctx.config_staged.flags = csd_window_flags_from_states_array(states); window->config_staged.flags = csd_window_flags_from_states_array(states);
} }
static void static void
@ -297,7 +370,8 @@ static const struct xdg_toplevel_listener xdg_toplevel_listener = {
static void static void
xdg_toplevel_decoration_configure(void *udata, struct zxdg_toplevel_decoration_v1 *toplevel, xdg_toplevel_decoration_configure(void *udata, struct zxdg_toplevel_decoration_v1 *toplevel,
uint32_t mode){ uint32_t mode){
ctx.config_staged.decoration_mode = mode; CSD_Window *window = &ctx.window;
window->config_staged.decoration_mode = mode;
} }
static const struct zxdg_toplevel_decoration_v1_listener static const struct zxdg_toplevel_decoration_v1_listener
@ -367,30 +441,31 @@ int main(){
/* create a window */ /* create a window */
{ {
/* window main surface */ /* window main surface */
ctx.main_wl_surface = wl_compositor_create_surface(ctx.wl_compositor); CSD_Window *window = &ctx.window;
ctx.main_xdg_surface = xdg_wm_base_get_xdg_surface(ctx.xdg_wm_base, ctx.main_wl_surface); window->main_wl_surface = wl_compositor_create_surface(ctx.wl_compositor);
xdg_surface_add_listener(ctx.main_xdg_surface, &xdg_surface_listener, 0); window->main_xdg_surface = xdg_wm_base_get_xdg_surface(ctx.xdg_wm_base, window->main_wl_surface);
ctx.main_xdg_toplevel = xdg_surface_get_toplevel(ctx.main_xdg_surface); xdg_surface_add_listener(window->main_xdg_surface, &xdg_surface_listener, 0);
xdg_toplevel_add_listener(ctx.main_xdg_toplevel, &xdg_toplevel_listener, 0); window->main_xdg_toplevel = xdg_surface_get_toplevel(window->main_xdg_surface);
xdg_toplevel_add_listener(window->main_xdg_toplevel, &xdg_toplevel_listener, 0);
ctx.control_flags = ~0; window->control_flags = ~0;
ctx.dim[0] = 640; window->dim[0] = 640;
ctx.dim[1] = 480; window->dim[1] = 480;
ctx.config_staged.decoration_mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; window->config_staged.decoration_mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
if (ctx.zxdg_decoration_manager != 0){ if (ctx.zxdg_decoration_manager != 0){
ctx.main_zxdg_toplevel_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(ctx.zxdg_decoration_manager, ctx.main_xdg_toplevel); window->main_zxdg_toplevel_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(ctx.zxdg_decoration_manager, window->main_xdg_toplevel);
zxdg_toplevel_decoration_v1_add_listener(ctx.main_zxdg_toplevel_decoration, &zxdg_toplevel_decoration_listener, 0); zxdg_toplevel_decoration_v1_add_listener(window->main_zxdg_toplevel_decoration, &zxdg_toplevel_decoration_listener, 0);
} }
for (int k = 0; k < 2; k += 1){ for (int k = 0; k < 2; k += 1){
ctx.mmbox[k][0] = 0; window->mmbox[k][0] = 0;
ctx.mmbox[k][1] = (1 << 30); window->mmbox[k][1] = (1 << 30);
} }
xdg_toplevel_set_app_id(ctx.main_xdg_toplevel, "demo"); xdg_toplevel_set_app_id(window->main_xdg_toplevel, "demo");
xdg_toplevel_set_title(ctx.main_xdg_toplevel, "Example Window"); xdg_toplevel_set_title(window->main_xdg_toplevel, "Example Window");
wl_surface_commit(ctx.main_wl_surface); wl_surface_commit(window->main_wl_surface);
/* window subsurface */ /* window subsurface */
ctx.gtk_window.shadow = csd_subsurface_new(); ctx.gtk_window.shadow = csd_subsurface_new();
@ -400,8 +475,8 @@ int main(){
csd_gtk_window_init(); csd_gtk_window_init();
/* window egl */ /* window egl */
ctx.main_wl_egl_window = wl_egl_window_create(ctx.main_wl_surface, ctx.main_wl_egl_window = wl_egl_window_create(window->main_wl_surface,
ctx.dim[0], ctx.dim[1]); window->dim[0], window->dim[1]);
EGLConfig configs[64]; EGLConfig configs[64];
EGLint config_cap = sizeof(configs)/sizeof(*configs); EGLint config_cap = sizeof(configs)/sizeof(*configs);
@ -481,81 +556,95 @@ int main(){
} }
} }
/* apply config */ {
if (ctx.config.serial != ctx.config_staged.serial){ CSD_Window *window = &ctx.window;
ctx.config = ctx.config_staged;
xdg_surface_ack_configure(ctx.main_xdg_surface, ctx.config.serial);
}
int csd = (ctx.config.decoration_mode == /* apply config */
ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE); if (window->config.serial != window->config_staged.serial){
window->config = window->config_staged;
/* window sizing */ xdg_surface_ack_configure(window->main_xdg_surface, window->config.serial);
memset(&ctx.csd_frame, 0, sizeof ctx.csd_frame);
memset(ctx.csd_dim, 0, sizeof ctx.csd_dim);
if (csd){
ctx.csd_frame = csd_gtk_calculate_frame();
}
for (int i = 0; i < 2; i += 1){
ctx.csd_dim[i] = ctx.csd_frame.border[i][0] + ctx.csd_frame.border[i][1];
}
for (int i = 0; i < 2; i += 1){
int32_t d = ctx.config.dim[i] - ctx.csd_dim[i];
if (!ctx.handled_first_size){
d = ctx.dim[i];
ctx.config.dim[i] = d + ctx.csd_dim[i];
} }
d = CSD_ClampBot(d, ctx.mmbox[i][0]);
d = CSD_ClampTop(d, ctx.mmbox[i][1]);
d = CSD_ClampBot(d, ctx.csd_frame.minbox[i]);
ctx.dim[i] = d;
}
ctx.handled_first_size = 1;
/* window size commit */ int csd = (window->config.decoration_mode ==
if (!(ctx.control_flags & CSD_WindowControlFlag_Resize)){ ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE);
xdg_toplevel_set_min_size(ctx.main_xdg_toplevel, ctx.dim[0], ctx.dim[1]);
xdg_toplevel_set_max_size(ctx.main_xdg_toplevel, ctx.dim[0], ctx.dim[1]); /* window sizing */
} memset(&window->csd_frame, 0, sizeof window->csd_frame);
else{ memset(window->csd_dim, 0, sizeof window->csd_dim);
if (csd){
window->csd_frame = csd_gtk_calculate_frame();
}
for (int i = 0; i < 2; i += 1){ for (int i = 0; i < 2; i += 1){
int32_t mw = CSD_ClampBot(ctx.mmbox[0][i], ctx.csd_frame.minbox[i]) + ctx.csd_dim[0]; window->csd_dim[i] = window->csd_frame.border[i][0] + window->csd_frame.border[i][1];
int32_t mh = ctx.mmbox[1][i] + ctx.csd_dim[1]; }
if (i == 0){ for (int i = 0; i < 2; i += 1){
xdg_toplevel_set_min_size(ctx.main_xdg_toplevel, mw, mh); int32_t d = window->config.dim[i] - window->csd_dim[i];
if (!window->handled_first_size){
d = window->dim[i];
window->config.dim[i] = d + window->csd_dim[i];
} }
else{ d = CSD_ClampBot(d, window->mmbox[i][0]);
xdg_toplevel_set_max_size(ctx.main_xdg_toplevel, mw, mh); d = CSD_ClampTop(d, window->mmbox[i][1]);
d = CSD_ClampBot(d, window->csd_frame.minbox[i]);
window->dim[i] = d;
}
window->handled_first_size = 1;
/* window size commit */
if (!(window->control_flags & CSD_WindowControlFlag_Resize)){
xdg_toplevel_set_min_size(window->main_xdg_toplevel,
window->dim[0], window->dim[1]);
xdg_toplevel_set_max_size(window->main_xdg_toplevel,
window->dim[0], window->dim[1]);
}
else{
for (int i = 0; i < 2; i += 1){
int32_t mw = window->csd_dim[0] + CSD_ClampBot(window->mmbox[0][i],
window->csd_frame.minbox[i]);
int32_t mh = window->mmbox[1][i] + window->csd_dim[1];
if (i == 0){
xdg_toplevel_set_min_size(window->main_xdg_toplevel, mw, mh);
}
else{
xdg_toplevel_set_max_size(window->main_xdg_toplevel, mw, mh);
}
} }
} }
} xdg_surface_set_window_geometry(window->main_xdg_surface,
xdg_surface_set_window_geometry(ctx.main_xdg_surface, -window->csd_frame.border[0][0],
-ctx.csd_frame.border[0][0], -window->csd_frame.border[1][0],
-ctx.csd_frame.border[1][0], window->dim[0] + window->csd_dim[0],
ctx.dim[0] + ctx.csd_dim[0], window->dim[1] + window->csd_dim[1]);
ctx.dim[1] + ctx.csd_dim[1]); wl_egl_window_resize(ctx.main_wl_egl_window,
wl_egl_window_resize(ctx.main_wl_egl_window, ctx.dim[0], ctx.dim[1], 0, 0); window->dim[0], window->dim[1], 0, 0);
/* frame update and render */ /* frame update and render */
ctx.cursor_shape = CSD_CursorShape_Pointer; ctx.cursor_shape = CSD_CursorShape_Pointer;
csd_gtk_update_and_render(); csd_gtk_update_and_render();
}
/* app update & render */ /* app update & render */
{ {
CSD_Window *window = &ctx.window;
if (ctx.close_signal){ if (ctx.close_signal){
exit_loop = 1; exit_loop = 1;
} }
glDrawBuffer(GL_BACK); glDrawBuffer(GL_BACK);
glViewport(0, 0, ctx.dim[0], ctx.dim[1]); glViewport(0, 0, window->dim[0], window->dim[1]);
glClearColor(0.40f, 0.90f, 0.15f, 1.f); glClearColor(0.40f, 0.90f, 0.15f, 1.f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
} }
eglSwapBuffers(ctx.egl_display, ctx.main_egl_surface);
wl_surface_commit(ctx.main_wl_surface); {
CSD_Window *window = &ctx.window;
eglSwapBuffers(ctx.egl_display, ctx.main_egl_surface);
wl_surface_commit(window->main_wl_surface);
}
/* commit new cursor */ /* commit new cursor */
{ {
CSD_Window *window = &ctx.window;
struct wl_cursor *cursor = ctx.wl_cursors[ctx.cursor_shape]; struct wl_cursor *cursor = ctx.wl_cursors[ctx.cursor_shape];
if (cursor != 0){ if (cursor != 0){
struct wl_cursor_image *cursor_image = cursor->images[0]; struct wl_cursor_image *cursor_image = cursor->images[0];
@ -565,7 +654,7 @@ int main(){
wl_surface_damage_buffer(ctx.cursor_surface, 0, 0, wl_surface_damage_buffer(ctx.cursor_surface, 0, 0,
cursor_image->width, cursor_image->height); cursor_image->width, cursor_image->height);
wl_surface_commit(ctx.cursor_surface); wl_surface_commit(ctx.cursor_surface);
wl_pointer_set_cursor(ctx.wl_pointer, ctx.serial, ctx.cursor_surface, wl_pointer_set_cursor(ctx.wl_pointer, window->serial, ctx.cursor_surface,
cursor_image->hotspot_x, cursor_image->hotspot_y); cursor_image->hotspot_x, cursor_image->hotspot_y);
} }
} }
@ -580,11 +669,12 @@ int main(){
static CSD_SubSurface static CSD_SubSurface
csd_subsurface_new(void){ csd_subsurface_new(void){
CSD_Window *window = &ctx.window;
CSD_SubSurface result = {0}; CSD_SubSurface result = {0};
result.wl_surface = wl_compositor_create_surface(ctx.wl_compositor); result.wl_surface = wl_compositor_create_surface(ctx.wl_compositor);
result.wl_subsurface = result.wl_subsurface =
wl_subcompositor_get_subsurface(ctx.wl_subcompositor, result.wl_surface, wl_subcompositor_get_subsurface(ctx.wl_subcompositor, result.wl_surface,
ctx.main_wl_surface); window->main_wl_surface);
return(result); return(result);
} }
@ -952,7 +1042,7 @@ csd_gtk_init(void){
static void static void
csd_gtk_window_init(void){ csd_gtk_window_init(void){
GTK_Window *gtk_window = &ctx.gtk_window; CSD_GTK_Window *gtk_window = &ctx.gtk_window;
gtk_window->header = gtk_header_bar_new(); gtk_window->header = gtk_header_bar_new();
gtk_window->window = gtk_offscreen_window_new(); gtk_window->window = gtk_offscreen_window_new();
@ -976,9 +1066,10 @@ csd_gtk_window_init(void){
static CSD_Frame static CSD_Frame
csd_gtk_calculate_frame(void){ csd_gtk_calculate_frame(void){
GTK_Window *gtk_window = &ctx.gtk_window; CSD_Window *window = &ctx.window;
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
CSD_Frame frame = {0}; CSD_Frame frame = {0};
bool show_title = (!(ctx.config.flags & CSD_WindowFlag_IsFullscreen)); bool show_title = (!(window->config.flags & CSD_WindowFlag_IsFullscreen));
if (show_title){ if (show_title){
gtk_widget_get_preferred_height(gtk_window->header, 0, &frame.border[1][0]); gtk_widget_get_preferred_height(gtk_window->header, 0, &frame.border[1][0]);
gtk_header_bar_set_title(GTK_HEADER_BAR(gtk_window->header), ""); gtk_header_bar_set_title(GTK_HEADER_BAR(gtk_window->header), "");
@ -1021,9 +1112,10 @@ csd_gtk__widget_from_name(GtkWidget *root, char *name){
static void static void
csd_gtk_update_and_render(void){ csd_gtk_update_and_render(void){
GTK_Window *gtk_window = &ctx.gtk_window; CSD_Window *window = &ctx.window;
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
if (ctx.control_flags & CSD_WindowControlFlag_Resize){ if (window->control_flags & CSD_WindowControlFlag_Resize){
static const CSD_CursorShape cursor_box[] = { static const CSD_CursorShape cursor_box[] = {
CSD_CursorShape_Resize_TopLeft, CSD_CursorShape_Resize_Top, CSD_CursorShape_Resize_TopRight, CSD_CursorShape_Resize_TopLeft, CSD_CursorShape_Resize_Top, CSD_CursorShape_Resize_TopRight,
CSD_CursorShape_Resize_Left, CSD_CursorShape_Pointer, CSD_CursorShape_Resize_Right, CSD_CursorShape_Resize_Left, CSD_CursorShape_Pointer, CSD_CursorShape_Resize_Right,
@ -1036,20 +1128,20 @@ csd_gtk_update_and_render(void){
XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT,
}; };
int l = (gtk_window->p[0] < 10); int l = (ctx.hover_p[0] < 0);
int r = (!l && gtk_window->p[0] >= ctx.dim[0] + 10); int r = (!l && ctx.hover_p[0] >= window->dim[0]);
int t = (gtk_window->p[1] < 10); int t = (ctx.hover_p[1] < -window->csd_frame.border[1][0]);
int b = (!t && gtk_window->p[1] >= ctx.dim[1] + 10); int b = (!t && ctx.hover_p[1] >= window->dim[1]);
int loc = 3*(b - t) + (r - l); int loc = 3*(b - t) + (r - l);
ctx.cursor_shape = cursor_box[4 + loc]; ctx.cursor_shape = cursor_box[4 + loc];
if (ctx.gtk_window.button == BTN_LEFT){ if (gtk_window->button == BTN_LEFT){
ctx.gtk_window.button = 0; gtk_window->button = 0;
if (loc != 0){ if (loc != 0){
xdg_toplevel_resize(ctx.main_xdg_toplevel, ctx.wl_seat, xdg_toplevel_resize(window->main_xdg_toplevel, ctx.wl_seat,
ctx.serial, xedge_box[4 + loc]); window->serial, xedge_box[4 + loc]);
} }
else{ else if (ctx.hover_p[1] < 0){
xdg_toplevel_move(ctx.main_xdg_toplevel, ctx.wl_seat, ctx.serial); xdg_toplevel_move(window->main_xdg_toplevel, ctx.wl_seat, window->serial);
} }
} }
} }
@ -1058,8 +1150,9 @@ csd_gtk_update_and_render(void){
CSD_SubSurface *subsurface = &gtk_window->shadow; CSD_SubSurface *subsurface = &gtk_window->shadow;
int32_t shadow_dim[2]; int32_t shadow_dim[2];
shadow_dim[0] = ctx.dim[0] + 2*SHADOW_MARGIN; shadow_dim[0] = window->dim[0] + 2*SHADOW_MARGIN;
shadow_dim[1] = ctx.dim[1] + 2*SHADOW_MARGIN + ctx.csd_frame.border[1][0]; shadow_dim[1] = (window->dim[1] + 2*SHADOW_MARGIN +
window->csd_frame.border[1][0]);
csd_subsurface_buffer_clear(subsurface); csd_subsurface_buffer_clear(subsurface);
csd_subsurface_buffer_alloc(subsurface, shadow_dim); csd_subsurface_buffer_alloc(subsurface, shadow_dim);
@ -1081,15 +1174,18 @@ csd_gtk_update_and_render(void){
64, 64); 64, 64);
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
cairo_rectangle(cr, cairo_rectangle(cr,
SHADOW_MARGIN, SHADOW_MARGIN + ctx.csd_frame.border[1][0], SHADOW_MARGIN,
ctx.dim[0], ctx.dim[1]); SHADOW_MARGIN + window->csd_frame.border[1][0],
window->dim[0], window->dim[1]);
cairo_fill(cr); cairo_fill(cr);
cairo_destroy(cr); cairo_destroy(cr);
cairo_surface_destroy(surface); cairo_surface_destroy(surface);
} }
csd_subsurface_set_position(subsurface, -SHADOW_MARGIN, -SHADOW_MARGIN - ctx.csd_frame.border[1][0]); csd_subsurface_set_position(subsurface,
-SHADOW_MARGIN,
-SHADOW_MARGIN - window->csd_frame.border[1][0]);
csd_subsurface_commit(subsurface); csd_subsurface_commit(subsurface);
} }
@ -1097,17 +1193,17 @@ csd_gtk_update_and_render(void){
CSD_SubSurface *subsurface = &gtk_window->titlebar; CSD_SubSurface *subsurface = &gtk_window->titlebar;
int32_t title_dim[2]; int32_t title_dim[2];
title_dim[0] = ctx.dim[0]; title_dim[0] = window->dim[0];
title_dim[1] = ctx.csd_frame.border[1][0]; title_dim[1] = window->csd_frame.border[1][0];
csd_subsurface_buffer_clear(subsurface); csd_subsurface_buffer_clear(subsurface);
csd_subsurface_buffer_alloc(subsurface, title_dim); csd_subsurface_buffer_alloc(subsurface, title_dim);
memset(subsurface->data, 0, subsurface->size); memset(subsurface->data, 0, subsurface->size);
{ {
int is_resizable = ((ctx.control_flags & CSD_WindowControlFlag_Resize) != 0); int is_resizable = ((window->control_flags & CSD_WindowControlFlag_Resize) != 0);
gtk_window_set_resizable(GTK_WINDOW(gtk_window->window), is_resizable); gtk_window_set_resizable(GTK_WINDOW(gtk_window->window), is_resizable);
if (!(ctx.config.flags & CSD_WindowFlag_IsActivated)){ if (!(window->config.flags & CSD_WindowFlag_IsActivated)){
gtk_widget_set_state_flags(gtk_window->window, GTK_STATE_FLAG_BACKDROP, true); gtk_widget_set_state_flags(gtk_window->window, GTK_STATE_FLAG_BACKDROP, true);
} }
else{ else{
@ -1117,7 +1213,7 @@ csd_gtk_update_and_render(void){
{ {
GtkStyleContext *style = gtk_widget_get_style_context(gtk_window->window); GtkStyleContext *style = gtk_widget_get_style_context(gtk_window->window);
if (ctx.config.flags & CSD_WindowMask_IsAnchored){ if (window->config.flags & CSD_WindowMask_IsAnchored){
gtk_style_context_add_class(style, "maximized"); gtk_style_context_add_class(style, "maximized");
} }
else{ else{
@ -1169,22 +1265,22 @@ csd_gtk_update_and_render(void){
/* buttons */ /* buttons */
uint32_t buttons[3] = {0}; uint32_t buttons[3] = {0};
int button_count = 0; int button_count = 0;
if (ctx.control_flags & CSD_WindowControlFlag_Min){ if (window->control_flags & CSD_WindowControlFlag_Min){
buttons[button_count] = 0; buttons[button_count] = 0;
button_count += 1; button_count += 1;
} }
if ((ctx.control_flags & CSD_WindowControlFlag_Max) && if ((window->control_flags & CSD_WindowControlFlag_Max) &&
(ctx.control_flags & CSD_WindowControlFlag_Resize)){ (window->control_flags & CSD_WindowControlFlag_Resize)){
buttons[button_count] = 1; buttons[button_count] = 1;
button_count += 1; button_count += 1;
} }
if (ctx.control_flags & CSD_WindowControlFlag_Close){ if (window->control_flags & CSD_WindowControlFlag_Close){
buttons[button_count] = 2; buttons[button_count] = 2;
button_count += 1; button_count += 1;
} }
for (int i = 0; i < button_count; i += 1){ for (int i = 0; i < button_count; i += 1){
uint32_t button_code = buttons[i]; CSD_U32 button_code = buttons[i];
char *button_name = ""; char *button_name = "";
char *icon_name = ""; char *icon_name = "";
@ -1195,7 +1291,7 @@ csd_gtk_update_and_render(void){
}break; }break;
case 1: { case 1: {
button_name = ".maximize"; button_name = ".maximize";
icon_name = ((ctx.config.flags & CSD_WindowFlag_IsMax) ? icon_name = ((window->config.flags & CSD_WindowFlag_IsMax) ?
"window-restore-symbolic" : "window-maximize-symbolic"); "window-restore-symbolic" : "window-maximize-symbolic");
}break; }break;
case 2: { case 2: {
@ -1212,7 +1308,7 @@ csd_gtk_update_and_render(void){
/* change style based on window state and focus */ /* change style based on window state and focus */
GtkStateFlags style_state = 0; GtkStateFlags style_state = 0;
if (!(ctx.config.flags & CSD_WindowFlag_IsActivated)){ if (!(window->config.flags & CSD_WindowFlag_IsActivated)){
style_state |= GTK_STATE_FLAG_BACKDROP; style_state |= GTK_STATE_FLAG_BACKDROP;
} }
if (gtk_window->hover_button_code == button_code){ if (gtk_window->hover_button_code == button_code){
@ -1305,7 +1401,7 @@ csd_gtk_update_and_render(void){
cairo_surface_destroy(cr_surface); cairo_surface_destroy(cr_surface);
} }
csd_subsurface_set_position(subsurface, 0, -ctx.csd_frame.border[1][0]); csd_subsurface_set_position(subsurface, 0, -window->csd_frame.border[1][0]);
csd_subsurface_commit(subsurface); csd_subsurface_commit(subsurface);
} }
} }

View File

@ -100,6 +100,26 @@ typedef struct CSD_SubSurface{
CSD_S32 p[2]; CSD_S32 p[2];
} CSD_SubSurface; } CSD_SubSurface;
typedef struct CSD_Window{
struct wl_surface *main_wl_surface;
struct xdg_surface *main_xdg_surface;
struct xdg_toplevel *main_xdg_toplevel;
struct zxdg_toplevel_decoration_v1 *main_zxdg_toplevel_decoration;
CSD_WindowControlFlags control_flags;
CSD_S32 mmbox[2][2];
CSD_Config config;
CSD_Config config_staged;
CSD_U32 serial;
CSD_Frame csd_frame;
CSD_S32 csd_dim[2];
CSD_B32 handled_first_size;
CSD_S32 dim[2];
} CSD_Window;
/* csd helpers */ /* csd helpers */
static CSD_SubSurface csd_subsurface_new(void); static CSD_SubSurface csd_subsurface_new(void);
@ -136,7 +156,6 @@ typedef struct CSD_GTK_Ctx{
} CSD_GTK_Ctx; } CSD_GTK_Ctx;
typedef struct CSD_GTK_Window{ typedef struct CSD_GTK_Window{
CSD_S32 p[2];
CSD_U32 button; CSD_U32 button;
CSD_S32 double_click_time_ms; CSD_S32 double_click_time_ms;
@ -148,7 +167,7 @@ typedef struct CSD_GTK_Window{
CSD_U32 hover_button_code; CSD_U32 hover_button_code;
CSD_U32 active_button_code; CSD_U32 active_button_code;
} GTK_Window; } CSD_GTK_Window;
/* csd gtk implementation */ /* csd gtk implementation */
@ -159,6 +178,13 @@ static CSD_Frame csd_gtk_calculate_frame(void);
static void csd_gtk_update_and_render(void); static void csd_gtk_update_and_render(void);
static void csd_gtk_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 */ /* csd gtk cairo shadow rendering */
static int csd_gtk_blur_surface(cairo_surface_t *surface, int margin); static int csd_gtk_blur_surface(cairo_surface_t *surface, int margin);
@ -202,33 +228,17 @@ typedef struct Ctx{
struct wl_surface *cursor_surface; struct wl_surface *cursor_surface;
struct wl_surface *hover_surface; struct wl_surface *hover_surface;
CSD_S32 hover_p[2];
CSD_CursorShape cursor_shape; CSD_CursorShape cursor_shape;
/* per-window: wayland */
struct wl_surface *main_wl_surface;
struct xdg_surface *main_xdg_surface;
struct xdg_toplevel *main_xdg_toplevel;
struct zxdg_toplevel_decoration_v1 *main_zxdg_toplevel_decoration;
/* per-window: egl */ /* per-window: egl */
struct wl_egl_window *main_wl_egl_window; struct wl_egl_window *main_wl_egl_window;
EGLSurface main_egl_surface; EGLSurface main_egl_surface;
/* per-window */ /* per-window */
CSD_WindowControlFlags control_flags; CSD_Window window;
int32_t dim[2]; CSD_GTK_Window gtk_window;
int32_t mmbox[2][2]; // [0][]:x [1][]:y [][0]:min [][1]:max
CSD_Config config;
CSD_Config config_staged;
CSD_U32 serial;
CSD_B32 handled_first_size;
CSD_Frame csd_frame;
CSD_S32 csd_dim[2];
GTK_Window gtk_window;
} Ctx; } Ctx;
#endif /* WAYLAND_GTK_EGL_EXAMPLE_H */ #endif /* WAYLAND_GTK_EGL_EXAMPLE_H */