[wayland_gtk_egl] full feature set up and running, some steps towards multi-seat support (not tested)
parent
070ab2f42f
commit
e0584cc5ea
|
|
@ -85,25 +85,22 @@ static const struct xdg_wm_base_listener xdg_wm_base_listener = {
|
|||
static void
|
||||
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_Seat *seat = &ctx.seat;
|
||||
CSD_Window *window = &ctx.window;
|
||||
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
|
||||
|
||||
CSD_S32 surface_off[2] = {0};
|
||||
if (surface == window->main_wl_surface){
|
||||
// surface_off = {0,0}
|
||||
if (csd_gtk_calc_surface_off(gtk_window, surface, surface_off)){
|
||||
// handled by gtk frame
|
||||
}
|
||||
else if (surface == gtk_window->titlebar.wl_surface){
|
||||
memcpy(surface_off, gtk_window->titlebar.p, sizeof(surface_off));
|
||||
}
|
||||
else if (surface == gtk_window->shadow.wl_surface){
|
||||
memcpy(surface_off, gtk_window->shadow.p, sizeof(surface_off));
|
||||
else if (surface == window->main_wl_surface){
|
||||
// app's surface_off = {0,0}
|
||||
}
|
||||
|
||||
CSD_Seat *seat = &ctx.seat;
|
||||
seat->hover_surface = surface;
|
||||
seat->serial = serial;
|
||||
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
|
||||
|
|
@ -117,20 +114,16 @@ pointer_leave(void *udata, struct wl_pointer *wl_pointer,
|
|||
static void
|
||||
pointer_motion(void *udata, struct wl_pointer *wl_pointer,
|
||||
CSD_U32 time, wl_fixed_t fx, wl_fixed_t fy){
|
||||
CSD_Seat *seat = &ctx.seat;
|
||||
CSD_Window *window = &ctx.window;
|
||||
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
|
||||
|
||||
CSD_Seat *seat = &ctx.seat;
|
||||
|
||||
CSD_S32 surface_off[2] = {0};
|
||||
if (seat->hover_surface == window->main_wl_surface){
|
||||
// surface_off = {0,0}
|
||||
if (csd_gtk_calc_surface_off(gtk_window, seat->hover_surface, surface_off)){
|
||||
// handled by gtk frame
|
||||
}
|
||||
else if (seat->hover_surface == gtk_window->titlebar.wl_surface){
|
||||
memcpy(surface_off, gtk_window->titlebar.p, sizeof(surface_off));
|
||||
}
|
||||
else if (seat->hover_surface == gtk_window->shadow.wl_surface){
|
||||
memcpy(surface_off, gtk_window->shadow.p, sizeof(surface_off));
|
||||
else if (seat->hover_surface == window->main_wl_surface){
|
||||
// app's surface_off = {0,0}
|
||||
}
|
||||
|
||||
seat->hover_p[0] = surface_off[0] + wl_fixed_to_int(fx);
|
||||
|
|
@ -154,7 +147,7 @@ pointer_button(void *udata, struct wl_pointer *wl_pointer,
|
|||
static void
|
||||
pointer_axis(void *udata, struct wl_pointer *wl_pointer,
|
||||
CSD_U32 time, CSD_U32 axis, wl_fixed_t fv){
|
||||
int v = wl_fixed_to_int(fv);
|
||||
CSD_S32 v = wl_fixed_to_int(fv);
|
||||
}
|
||||
|
||||
static const struct wl_pointer_listener pointer_listener = {
|
||||
|
|
@ -217,7 +210,8 @@ registry_global(void *udata, struct wl_registry *wl_registry,
|
|||
else if (strcmp(interface, "wl_seat") == 0){
|
||||
CSD_Seat *seat = &ctx.seat;
|
||||
if (seat->wl_seat == 0){
|
||||
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, 0);
|
||||
seat->cursor_surface = wl_compositor_create_surface(ctx.wl_compositor);
|
||||
}
|
||||
|
|
@ -246,7 +240,8 @@ static const struct xdg_surface_listener xdg_surface_listener = {
|
|||
|
||||
static void
|
||||
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){
|
||||
window->config_staged.dim[0] = width;
|
||||
|
|
@ -353,42 +348,18 @@ int main(){
|
|||
/* create a window */
|
||||
{
|
||||
/* window main surface */
|
||||
CSD_Window *window = &ctx.window;
|
||||
window->main_wl_surface = wl_compositor_create_surface(ctx.wl_compositor);
|
||||
window->main_xdg_surface = xdg_wm_base_get_xdg_surface(ctx.xdg_wm_base, window->main_wl_surface);
|
||||
xdg_surface_add_listener(window->main_xdg_surface, &xdg_surface_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);
|
||||
|
||||
window->control_flags = ~0;
|
||||
|
||||
window->dim[0] = 640;
|
||||
window->dim[1] = 480;
|
||||
window->config_staged.decoration_mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
|
||||
if (ctx.zxdg_decoration_manager != 0){
|
||||
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(window->main_zxdg_toplevel_decoration, &zxdg_toplevel_decoration_listener, 0);
|
||||
}
|
||||
|
||||
for (int k = 0; k < 2; k += 1){
|
||||
window->mmbox[k][0] = 0;
|
||||
window->mmbox[k][1] = (1 << 30);
|
||||
}
|
||||
|
||||
xdg_toplevel_set_app_id(window->main_xdg_toplevel, "demo");
|
||||
xdg_toplevel_set_title(window->main_xdg_toplevel, "Example Window");
|
||||
wl_surface_commit(window->main_wl_surface);
|
||||
|
||||
/* window subsurface */
|
||||
ctx.gtk_window.shadow = csd_subsurface_new();
|
||||
ctx.gtk_window.titlebar = csd_subsurface_new();
|
||||
csd_window_init(&ctx.window);
|
||||
|
||||
/* window gtk */
|
||||
csd_gtk_window_init();
|
||||
csd_gtk_window_init(&ctx.gtk_window);
|
||||
}
|
||||
|
||||
/* window egl */
|
||||
{
|
||||
CSD_Window *window = &ctx.window;
|
||||
ctx.main_wl_egl_window = wl_egl_window_create(window->main_wl_surface,
|
||||
window->dim[0], window->dim[1]);
|
||||
window->dim[0],
|
||||
window->dim[1]);
|
||||
|
||||
EGLConfig configs[64];
|
||||
EGLint config_cap = sizeof(configs)/sizeof(*configs);
|
||||
|
|
@ -406,7 +377,8 @@ int main(){
|
|||
EGL_STENCIL_SIZE, 8,
|
||||
EGL_NONE,
|
||||
};
|
||||
eglChooseConfig(ctx.egl_display, attributes, configs, config_cap, &config_count);
|
||||
eglChooseConfig(ctx.egl_display, attributes,
|
||||
configs, config_cap, &config_count);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -415,7 +387,9 @@ int main(){
|
|||
EGL_NONE,
|
||||
};
|
||||
for (EGLint i = 0; i < config_count; i += 1){
|
||||
ctx.main_egl_surface = eglCreateWindowSurface(ctx.egl_display, configs[i], ctx.main_wl_egl_window, attributes);
|
||||
ctx.main_egl_surface =
|
||||
eglCreateWindowSurface(ctx.egl_display, configs[i],
|
||||
ctx.main_wl_egl_window, attributes);
|
||||
if (ctx.main_egl_surface != EGL_NO_SURFACE){
|
||||
break;
|
||||
}
|
||||
|
|
@ -468,75 +442,29 @@ int main(){
|
|||
}
|
||||
}
|
||||
|
||||
{
|
||||
CSD_Window *window = &ctx.window;
|
||||
/* setup seats list for frame */
|
||||
CSD_Seat *seats[] = {&ctx.seat};
|
||||
CSD_U32 seat_count = 1;
|
||||
|
||||
/* apply config */
|
||||
if (window->config.serial != window->config_staged.serial){
|
||||
window->config = window->config_staged;
|
||||
xdg_surface_ack_configure(window->main_xdg_surface, window->config.serial);
|
||||
for (CSD_U32 si = 0; si < seat_count; si += 1){
|
||||
seats[si]->cursor_shape = CSD_CursorShape_Hidden;
|
||||
}
|
||||
|
||||
int csd = (window->config.decoration_mode ==
|
||||
ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE);
|
||||
/* apply new window config */
|
||||
csd_window_apply_new_config(&ctx.window);
|
||||
|
||||
/* window sizing */
|
||||
memset(&window->csd_frame, 0, sizeof window->csd_frame);
|
||||
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){
|
||||
window->csd_dim[i] = window->csd_frame.border[i][0] + window->csd_frame.border[i][1];
|
||||
}
|
||||
for (int i = 0; i < 2; i += 1){
|
||||
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];
|
||||
}
|
||||
d = CSD_ClampBot(d, window->mmbox[i][0]);
|
||||
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;
|
||||
/* calculate csd frame */
|
||||
CSD_Frame csd_frame = csd_gtk_calc_frame(&ctx.window, &ctx.gtk_window);
|
||||
|
||||
/* 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,
|
||||
-window->csd_frame.border[0][0],
|
||||
-window->csd_frame.border[1][0],
|
||||
window->dim[0] + window->csd_dim[0],
|
||||
window->dim[1] + window->csd_dim[1]);
|
||||
/* window size update */
|
||||
csd_window_size_update(&ctx.window, &csd_frame);
|
||||
|
||||
/* egl size update */
|
||||
wl_egl_window_resize(ctx.main_wl_egl_window,
|
||||
window->dim[0], window->dim[1], 0, 0);
|
||||
}
|
||||
ctx.window.dim[0], ctx.window.dim[1], 0, 0);
|
||||
|
||||
/* frame update and render */
|
||||
{
|
||||
CSD_Seat *seat = &ctx.seat;
|
||||
seat->cursor_shape = CSD_CursorShape_Pointer;
|
||||
csd_gtk_update_and_render();
|
||||
}
|
||||
csd_gtk_update_and_render(&ctx.window, &ctx.gtk_window, seats, seat_count);
|
||||
|
||||
/* app update & render */
|
||||
{
|
||||
|
|
@ -544,6 +472,19 @@ int main(){
|
|||
if (ctx.close_signal){
|
||||
exit_loop = 1;
|
||||
}
|
||||
else if (ctx.minimize_signal){
|
||||
ctx.minimize_signal = 0;
|
||||
xdg_toplevel_set_minimized(window->main_xdg_toplevel);
|
||||
}
|
||||
else if (ctx.maximize_signal){
|
||||
ctx.maximize_signal = 0;
|
||||
if (window->config.flags & CSD_WindowFlag_IsMax){
|
||||
xdg_toplevel_unset_maximized(window->main_xdg_toplevel);
|
||||
}
|
||||
else{
|
||||
xdg_toplevel_set_maximized(window->main_xdg_toplevel);
|
||||
}
|
||||
}
|
||||
|
||||
glDrawBuffer(GL_BACK);
|
||||
glViewport(0, 0, window->dim[0], window->dim[1]);
|
||||
|
|
@ -560,7 +501,6 @@ int main(){
|
|||
/* commit new cursor */
|
||||
{
|
||||
CSD_Seat *seat = &ctx.seat;
|
||||
CSD_Window *window = &ctx.window;
|
||||
struct wl_cursor *cursor = ctx.wl_cursors[seat->cursor_shape];
|
||||
if (cursor != 0){
|
||||
struct wl_cursor_image *cursor_image = cursor->images[0];
|
||||
|
|
@ -583,6 +523,103 @@ int main(){
|
|||
|
||||
/* csd helpers */
|
||||
|
||||
static void
|
||||
csd_window_init(CSD_Window *window){
|
||||
window->main_wl_surface = wl_compositor_create_surface(ctx.wl_compositor);
|
||||
window->main_xdg_surface = xdg_wm_base_get_xdg_surface(ctx.xdg_wm_base, window->main_wl_surface);
|
||||
xdg_surface_add_listener(window->main_xdg_surface, &xdg_surface_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);
|
||||
|
||||
window->control_flags = ~0;
|
||||
|
||||
window->dim[0] = 640;
|
||||
window->dim[1] = 480;
|
||||
window->config_staged.decoration_mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
|
||||
if (ctx.zxdg_decoration_manager != 0){
|
||||
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(window->main_zxdg_toplevel_decoration,
|
||||
&zxdg_toplevel_decoration_listener, 0);
|
||||
}
|
||||
|
||||
for (int k = 0; k < 2; k += 1){
|
||||
window->mmbox[k][0] = 1;
|
||||
window->mmbox[k][1] = (1 << 30);
|
||||
}
|
||||
|
||||
xdg_toplevel_set_app_id(window->main_xdg_toplevel, "demo");
|
||||
xdg_toplevel_set_title(window->main_xdg_toplevel, "Example Window");
|
||||
wl_surface_commit(window->main_wl_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
csd_window_apply_new_config(CSD_Window *window){
|
||||
if (window->config.serial != window->config_staged.serial){
|
||||
window->config = window->config_staged;
|
||||
xdg_surface_ack_configure(window->main_xdg_surface, window->config.serial);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
csd_window_size_update(CSD_Window *window, CSD_Frame *csd_frame){
|
||||
/* window sizing */
|
||||
memset(&window->csd_frame, 0, sizeof window->csd_frame);
|
||||
memset(window->csd_dim, 0, sizeof window->csd_dim);
|
||||
if (window->config.decoration_mode ==
|
||||
ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){
|
||||
window->csd_frame = *csd_frame;
|
||||
for (CSD_U32 i = 0; i < 2; i += 1){
|
||||
window->csd_dim[i] = (csd_frame->border[i][0] +
|
||||
csd_frame->border[i][1]);
|
||||
}
|
||||
}
|
||||
for (CSD_U32 i = 0; i < 2; i += 1){
|
||||
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];
|
||||
}
|
||||
d = CSD_ClampBot(d, window->mmbox[i][0]);
|
||||
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 (CSD_S32 i = 0; i < 2; i += 1){
|
||||
CSD_S32 m[2];
|
||||
for (CSD_S32 k = 0; k < 2; k += 1){
|
||||
m[k] = window->mmbox[k][i];
|
||||
if (i == 0){
|
||||
m[k] = CSD_ClampBot(m[k], window->csd_frame.minbox[k]);
|
||||
}
|
||||
m[k] += window->csd_dim[k];
|
||||
}
|
||||
if (i == 0){
|
||||
xdg_toplevel_set_min_size(window->main_xdg_toplevel, m[0], m[1]);
|
||||
}
|
||||
else{
|
||||
xdg_toplevel_set_max_size(window->main_xdg_toplevel, m[0], m[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
xdg_surface_set_window_geometry(window->main_xdg_surface,
|
||||
-window->csd_frame.border[0][0],
|
||||
-window->csd_frame.border[1][0],
|
||||
window->dim[0] + window->csd_dim[0],
|
||||
window->dim[1] + window->csd_dim[1]);
|
||||
}
|
||||
|
||||
static CSD_SubSurface
|
||||
csd_subsurface_new(void){
|
||||
CSD_Window *window = &ctx.window;
|
||||
|
|
@ -957,8 +994,9 @@ csd_gtk_init(void){
|
|||
}
|
||||
|
||||
static void
|
||||
csd_gtk_window_init(void){
|
||||
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
|
||||
csd_gtk_window_init(CSD_GTK_Window *gtk_window){
|
||||
gtk_window->shadow = csd_subsurface_new();
|
||||
gtk_window->titlebar = csd_subsurface_new();
|
||||
|
||||
gtk_window->header = gtk_header_bar_new();
|
||||
gtk_window->window = gtk_offscreen_window_new();
|
||||
|
|
@ -981,11 +1019,9 @@ csd_gtk_window_init(void){
|
|||
}
|
||||
|
||||
static CSD_Frame
|
||||
csd_gtk_calculate_frame(void){
|
||||
CSD_Window *window = &ctx.window;
|
||||
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
|
||||
csd_gtk_calc_frame(CSD_Window *window, CSD_GTK_Window *gtk_window){
|
||||
CSD_Frame frame = {0};
|
||||
bool show_title = (!(window->config.flags & CSD_WindowFlag_IsFullscreen));
|
||||
CSD_B32 show_title = (!(window->config.flags & CSD_WindowFlag_IsFullscreen));
|
||||
if (show_title){
|
||||
gtk_widget_get_preferred_height(gtk_window->header, 0, &frame.border[1][0]);
|
||||
gtk_header_bar_set_title(GTK_HEADER_BAR(gtk_window->header), "");
|
||||
|
|
@ -995,6 +1031,21 @@ csd_gtk_calculate_frame(void){
|
|||
return(frame);
|
||||
}
|
||||
|
||||
static CSD_B32
|
||||
csd_gtk_calc_surface_off(CSD_GTK_Window *gtk_window, struct wl_surface *surface,
|
||||
CSD_S32 *off){
|
||||
CSD_B32 result = 0;
|
||||
if (surface == gtk_window->titlebar.wl_surface){
|
||||
memcpy(off, gtk_window->titlebar.p, sizeof(gtk_window->titlebar.p));
|
||||
result = 1;
|
||||
}
|
||||
else if (surface == gtk_window->shadow.wl_surface){
|
||||
memcpy(off, gtk_window->shadow.p, sizeof(gtk_window->shadow.p));
|
||||
result = 1;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
typedef struct CSD_GTK_FindWidgetVars{
|
||||
char *name;
|
||||
GtkWidget *widget;
|
||||
|
|
@ -1027,30 +1078,57 @@ csd_gtk__widget_from_name(GtkWidget *root, char *name){
|
|||
#define SHADOW_MARGIN 24
|
||||
|
||||
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;
|
||||
csd_gtk_update_and_render(CSD_Window *window, CSD_GTK_Window *gtk_window,
|
||||
CSD_Seat **seats, CSD_U32 seat_count){
|
||||
|
||||
/* determine cursor location information */
|
||||
/* setup buttons */
|
||||
enum{
|
||||
HEADER_BUTTON_NULL,
|
||||
HEADER_BUTTON_MIN, HEADER_BUTTON_MAX, HEADER_BUTTON_CLOSE,
|
||||
HEADER_BUTTON_COUNT
|
||||
};
|
||||
static char* header_button_name[] = {
|
||||
0, ".minimize", ".maximize", ".close"
|
||||
};
|
||||
CSD_B32 header_button_active[] = {
|
||||
/*NULL*/ 0,
|
||||
/*MIN*/ (window->control_flags & CSD_WindowControlFlag_Min),
|
||||
/*MAX*/ ((window->control_flags & CSD_WindowControlFlag_Max) &&
|
||||
(window->control_flags & CSD_WindowControlFlag_Resize)),
|
||||
/*CLOSE*/ (window->control_flags & CSD_WindowControlFlag_Close)
|
||||
};
|
||||
|
||||
/* per-cursor locals */
|
||||
enum{
|
||||
LOCATION_NULL, LOCATION_SHADOW, LOCATION_TITLEBAR,
|
||||
};
|
||||
CSD_U32 cursor_loc = LOCATION_NULL;
|
||||
CSD_S32 cursor_shadow_loc = 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]);
|
||||
cursor_shadow_loc = 3*(b - t) + (r - l);
|
||||
}
|
||||
if (cursor_shadow_loc != 0){
|
||||
cursor_loc = LOCATION_SHADOW;
|
||||
struct CursorVars{
|
||||
CSD_U32 loc;
|
||||
CSD_S32 shadow_loc;
|
||||
CSD_U32 header_button_hover;
|
||||
} CursorVars;
|
||||
struct CursorVars *cursors = alloca(sizeof(struct CursorVars)*seat_count);
|
||||
memset(cursors, 0, sizeof(struct CursorVars)*seat_count);
|
||||
|
||||
/* determine cursor location information */
|
||||
for (CSD_U32 si = 0; si < seat_count; si += 1){
|
||||
CSD_Seat *seat = seats[si];
|
||||
|
||||
if (seat->hover_surface == window->main_wl_surface ||
|
||||
seat->hover_surface == gtk_window->titlebar.wl_surface ||
|
||||
seat->hover_surface == gtk_window->shadow.wl_surface){
|
||||
CSD_B32 l = (seat->hover_p[0] < 0);
|
||||
CSD_B32 r = (!l && seat->hover_p[0] >= window->dim[0]);
|
||||
CSD_B32 t = (seat->hover_p[1] < -window->csd_frame.border[1][0]);
|
||||
CSD_B32 b = (!t && seat->hover_p[1] >= window->dim[1]);
|
||||
|
||||
cursors[si].shadow_loc = 3*(b - t) + (r - l);
|
||||
if (cursors[si].shadow_loc != 0){
|
||||
cursors[si].loc = LOCATION_SHADOW;
|
||||
}
|
||||
else if (seat->hover_p[1] < 0){
|
||||
cursor_loc = LOCATION_TITLEBAR;
|
||||
cursors[si].loc = LOCATION_TITLEBAR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1098,25 +1176,6 @@ csd_gtk_update_and_render(void){
|
|||
csd_subsurface_commit(subsurface);
|
||||
}
|
||||
|
||||
|
||||
/* setup buttons */
|
||||
enum{
|
||||
HEADER_BUTTON_NULL,
|
||||
HEADER_BUTTON_MIN, HEADER_BUTTON_MAX, HEADER_BUTTON_CLOSE,
|
||||
HEADER_BUTTON_COUNT
|
||||
};
|
||||
static char* header_button_name[] = {
|
||||
0, ".minimize", ".maximize", ".close"
|
||||
};
|
||||
CSD_B32 header_button_active[] = {
|
||||
/*NULL*/ 0,
|
||||
/*MIN*/ (window->control_flags & CSD_WindowControlFlag_Min),
|
||||
/*MAX*/ ((window->control_flags & CSD_WindowControlFlag_Max) &&
|
||||
(window->control_flags & CSD_WindowControlFlag_Resize)),
|
||||
/*CLOSE*/ (window->control_flags & CSD_WindowControlFlag_Close)
|
||||
};
|
||||
CSD_U32 header_button_hover = 0;
|
||||
|
||||
/* draw frame */
|
||||
{
|
||||
CSD_SubSurface *subsurface = >k_window->titlebar;
|
||||
|
|
@ -1216,19 +1275,23 @@ csd_gtk_update_and_render(void){
|
|||
GtkAllocation rect;
|
||||
gtk_widget_get_clip(widget, &rect);
|
||||
|
||||
/* check pointer hover */
|
||||
CSD_B32 is_hovered = 0;
|
||||
{
|
||||
CSD_S32 x0 = rect.x;
|
||||
CSD_S32 y0 = rect.y - title_dim[1];
|
||||
CSD_S32 x1 = rect.x + rect.width;
|
||||
CSD_S32 y1 = rect.y + rect.height - title_dim[1];
|
||||
|
||||
/* check pointer hover */
|
||||
CSD_B32 is_hovered = 0;
|
||||
for (CSD_U32 si = 0; si < seat_count; si += 1){
|
||||
if (cursors[si].loc == LOCATION_TITLEBAR){
|
||||
CSD_Seat *seat = seats[si];
|
||||
if (x0 <= seat->hover_p[0] && seat->hover_p[0] < x1 &&
|
||||
y0 <= seat->hover_p[1] && seat->hover_p[1] < y1){
|
||||
header_button_hover = i;
|
||||
cursors[si].header_button_hover = i;
|
||||
is_hovered = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* change style based on window state and focus */
|
||||
GtkStyleContext *style = gtk_widget_get_style_context(widget);
|
||||
|
|
@ -1324,26 +1387,30 @@ csd_gtk_update_and_render(void){
|
|||
/* handle left-button press */
|
||||
if (ctx.event_button == BTN_LEFT &&
|
||||
ctx.event_button_state == 1){
|
||||
switch (cursor_loc){
|
||||
CSD_U32 si = 0;
|
||||
switch (cursors[si].loc){
|
||||
default: case LOCATION_NULL: break;
|
||||
|
||||
case LOCATION_SHADOW: {
|
||||
#define X(N) XDG_TOPLEVEL_RESIZE_EDGE_##N
|
||||
static const enum xdg_toplevel_resize_edge xedge_box[] = {
|
||||
XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_TOP, XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT,
|
||||
XDG_TOPLEVEL_RESIZE_EDGE_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_NONE, XDG_TOPLEVEL_RESIZE_EDGE_RIGHT,
|
||||
XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT,
|
||||
X(TOP_LEFT), X(TOP), X(TOP_RIGHT),
|
||||
X(LEFT), X(NONE), X(RIGHT),
|
||||
X(BOTTOM_LEFT), X(BOTTOM), X(BOTTOM_RIGHT),
|
||||
};
|
||||
xdg_toplevel_resize(window->main_xdg_toplevel, seat->wl_seat,
|
||||
seat->serial, xedge_box[4 + cursor_shadow_loc]);
|
||||
#undef X
|
||||
xdg_toplevel_resize(window->main_xdg_toplevel, seats[si]->wl_seat,
|
||||
seats[si]->serial, xedge_box[4 + cursors[si].shadow_loc]);
|
||||
ctx.has_event = 0;
|
||||
}break;
|
||||
|
||||
case LOCATION_TITLEBAR: {
|
||||
if (header_button_hover == 0){
|
||||
xdg_toplevel_move(window->main_xdg_toplevel, seat->wl_seat, seat->serial);
|
||||
if (cursors[si].header_button_hover == 0){
|
||||
xdg_toplevel_move(window->main_xdg_toplevel,
|
||||
seats[si]->wl_seat, seats[si]->serial);
|
||||
}
|
||||
else{
|
||||
gtk_window->active_header_button = header_button_hover;
|
||||
gtk_window->active_header_button = cursors[si].header_button_hover;
|
||||
}
|
||||
ctx.has_event = 0;
|
||||
}break;
|
||||
|
|
@ -1353,25 +1420,31 @@ csd_gtk_update_and_render(void){
|
|||
/* handle left-button release */
|
||||
if (ctx.event_button == BTN_LEFT &&
|
||||
ctx.event_button_state == 0){
|
||||
CSD_U32 si = 0;
|
||||
if (gtk_window->active_header_button != 0 &&
|
||||
gtk_window->active_header_button == header_button_hover){
|
||||
// activate button effect here
|
||||
gtk_window->active_header_button == cursors[si].header_button_hover){
|
||||
switch (gtk_window->active_header_button){
|
||||
case HEADER_BUTTON_MIN: { ctx.minimize_signal = 1; } break;
|
||||
case HEADER_BUTTON_MAX: { ctx.maximize_signal = 1; } break;
|
||||
case HEADER_BUTTON_CLOSE: { ctx.close_signal = 1; } break;
|
||||
}
|
||||
gtk_window->active_header_button = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set cursor shape */
|
||||
for (CSD_U32 si = 0; si < seat_count; si += 1){
|
||||
if (window->control_flags & CSD_WindowControlFlag_Resize){
|
||||
#define X(N) CSD_CursorShape_##N
|
||||
static const CSD_CursorShape cursor_box[] = {
|
||||
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_BottomLeft, CSD_CursorShape_Resize_Bottom, CSD_CursorShape_Resize_BottomRight,
|
||||
X(Resize_TopLeft), X(Resize_Top), X(Resize_TopRight),
|
||||
X(Resize_Left), X(Pointer), X(Resize_Right),
|
||||
X(Resize_BottomLeft), X(Resize_Bottom), X(Resize_BottomRight),
|
||||
};
|
||||
seat->cursor_shape = cursor_box[4 + cursor_shadow_loc];
|
||||
#undef X
|
||||
seats[si]->cursor_shape = cursor_box[4 + cursors[si].shadow_loc];
|
||||
}
|
||||
else{
|
||||
seat->cursor_shape = CSD_CursorShape_Pointer;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -133,6 +133,10 @@ typedef struct CSD_Seat{
|
|||
|
||||
/* csd helpers */
|
||||
|
||||
static void csd_window_init(CSD_Window *window);
|
||||
static void csd_window_apply_new_config(CSD_Window *window);
|
||||
static void csd_window_size_update(CSD_Window *window, CSD_Frame *csd_frame);
|
||||
|
||||
static CSD_SubSurface csd_subsurface_new(void);
|
||||
static void csd_subsurface_buffer_clear(CSD_SubSurface *subsurface);
|
||||
static void csd_subsurface_buffer_alloc(CSD_SubSurface *subsurface, CSD_S32 dim[2]);
|
||||
|
|
@ -180,10 +184,14 @@ typedef struct CSD_GTK_Window{
|
|||
/* csd gtk implementation */
|
||||
|
||||
static void csd_gtk_init(void);
|
||||
static void csd_gtk_window_init(void);
|
||||
static CSD_Frame csd_gtk_calculate_frame(void);
|
||||
static void csd_gtk_window_init(CSD_GTK_Window *gtk_window);
|
||||
static CSD_Frame csd_gtk_calc_frame(CSD_Window *window, CSD_GTK_Window *gtk_window);
|
||||
static CSD_B32 csd_gtk_calc_surface_off(CSD_GTK_Window *gtk_window,
|
||||
struct wl_surface *surface,
|
||||
CSD_S32 *off);
|
||||
|
||||
static void csd_gtk_update_and_render(void);
|
||||
static void csd_gtk_update_and_render(CSD_Window *window, CSD_GTK_Window *gtk_window,
|
||||
CSD_Seat **seats, CSD_U32 seat_count);
|
||||
|
||||
/* csd gtk cairo shadow rendering */
|
||||
|
||||
|
|
@ -198,6 +206,8 @@ static void csd_gtk_render_shadow(cairo_t *cr, cairo_surface_t *surface,
|
|||
typedef struct Ctx{
|
||||
/* the rest */
|
||||
CSD_B32 close_signal;
|
||||
CSD_B32 minimize_signal;
|
||||
CSD_B32 maximize_signal;
|
||||
|
||||
CSD_B32 has_event;
|
||||
CSD_U32 event_button;
|
||||
|
|
|
|||
Loading…
Reference in New Issue