Compare commits
No commits in common. "070ab2f42f0c155e806e0677fe5cdc7eccab626e" and "1acd34888634a9f2a52225d3dfc40a1a26207cab" have entirely different histories.
070ab2f42f
...
1acd348886
|
|
@ -67,14 +67,14 @@ GL_FUNCS_XLIST(X)
|
||||||
static Ctx ctx = {0};
|
static Ctx ctx = {0};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
shm_format(void *udata, struct wl_shm *wl_shm, CSD_U32 format){}
|
shm_format(void *udata, struct wl_shm *wl_shm, uint32_t format){}
|
||||||
|
|
||||||
static const struct wl_shm_listener shm_listener = {
|
static const struct wl_shm_listener shm_listener = {
|
||||||
shm_format
|
shm_format
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xdg_wm_base_ping(void *udata, struct xdg_wm_base *xdg_wm_base, CSD_U32 serial){
|
xdg_wm_base_ping(void *udata, struct xdg_wm_base *xdg_wm_base, uint32_t serial){
|
||||||
xdg_wm_base_pong(xdg_wm_base, serial);
|
xdg_wm_base_pong(xdg_wm_base, serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,78 +83,169 @@ static const struct xdg_wm_base_listener xdg_wm_base_listener = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pointer_enter(void *udata, struct wl_pointer *wl_pointer, CSD_U32 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_Window *window = &ctx.window;
|
||||||
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
|
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
|
||||||
|
|
||||||
CSD_S32 surface_off[2] = {0};
|
int32_t x = wl_fixed_to_int(fx);
|
||||||
|
int32_t y = wl_fixed_to_int(fy);
|
||||||
if (surface == window->main_wl_surface){
|
if (surface == window->main_wl_surface){
|
||||||
// surface_off = {0,0}
|
printf("pointer_enter (main) %d,%d\n", x, y);
|
||||||
}
|
}
|
||||||
else if (surface == gtk_window->titlebar.wl_surface){
|
else if (surface == gtk_window->titlebar.wl_surface){
|
||||||
memcpy(surface_off, gtk_window->titlebar.p, sizeof(surface_off));
|
x += gtk_window->titlebar.p[0];
|
||||||
|
y += gtk_window->titlebar.p[1];
|
||||||
|
printf("pointer_enter (titlebar) %d,%d\n", x, y);
|
||||||
}
|
}
|
||||||
else if (surface == gtk_window->shadow.wl_surface){
|
else if (surface == gtk_window->shadow.wl_surface){
|
||||||
memcpy(surface_off, gtk_window->shadow.p, sizeof(surface_off));
|
x += gtk_window->shadow.p[0];
|
||||||
|
y += gtk_window->shadow.p[1];
|
||||||
|
printf("pointer_enter (shadow) %d,%d\n", x, y);
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
CSD_Seat *seat = &ctx.seat;
|
printf("pointer_enter (unidentified) %d,%d\n", x, y);
|
||||||
seat->hover_surface = surface;
|
}
|
||||||
seat->hover_p[0] = surface_off[0] + wl_fixed_to_int(fx);
|
window->serial = serial;
|
||||||
seat->hover_p[1] = surface_off[1] + wl_fixed_to_int(fy);
|
ctx.hover_surface = surface;
|
||||||
seat->serial = serial;
|
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,
|
pointer_leave(void *udata, struct wl_pointer *wl_pointer, uint32_t serial,
|
||||||
CSD_U32 serial, struct wl_surface *surface){
|
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,
|
|
||||||
CSD_U32 time, wl_fixed_t fx, wl_fixed_t fy){
|
|
||||||
CSD_Window *window = &ctx.window;
|
CSD_Window *window = &ctx.window;
|
||||||
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
|
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
|
||||||
|
|
||||||
CSD_Seat *seat = &ctx.seat;
|
if (surface == window->main_wl_surface){
|
||||||
|
printf("pointer_leave (main)\n");
|
||||||
CSD_S32 surface_off[2] = {0};
|
|
||||||
if (seat->hover_surface == window->main_wl_surface){
|
|
||||||
// surface_off = {0,0}
|
|
||||||
}
|
}
|
||||||
else if (seat->hover_surface == gtk_window->titlebar.wl_surface){
|
else if (surface == gtk_window->titlebar.wl_surface){
|
||||||
memcpy(surface_off, gtk_window->titlebar.p, sizeof(surface_off));
|
printf("pointer_leave (titlebar)\n");
|
||||||
}
|
}
|
||||||
else if (seat->hover_surface == gtk_window->shadow.wl_surface){
|
else if (surface == gtk_window->shadow.wl_surface){
|
||||||
memcpy(surface_off, gtk_window->shadow.p, sizeof(surface_off));
|
printf("pointer_leave (shadow)\n");
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
seat->hover_p[0] = surface_off[0] + wl_fixed_to_int(fx);
|
printf("pointer_leave (unidentified)\n");
|
||||||
seat->hover_p[1] = surface_off[1] + wl_fixed_to_int(fy);
|
}
|
||||||
|
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_button(void *udata, struct wl_pointer *wl_pointer,
|
pointer_motion(void *udata, struct wl_pointer *wl_pointer, uint32_t time,
|
||||||
CSD_U32 serial, CSD_U32 time, CSD_U32 button, CSD_U32 state){
|
wl_fixed_t fx, wl_fixed_t fy){
|
||||||
CSD_Seat *seat = &ctx.seat;
|
|
||||||
CSD_Window *window = &ctx.window;
|
CSD_Window *window = &ctx.window;
|
||||||
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
|
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
|
||||||
{
|
|
||||||
ctx.has_event = 1;
|
int32_t x = wl_fixed_to_int(fx);
|
||||||
ctx.event_button = button;
|
int32_t y = wl_fixed_to_int(fy);
|
||||||
ctx.event_button_state = state;
|
if (ctx.hover_surface == window->main_wl_surface){
|
||||||
|
printf("pointer_motion (main) %d,%d\n", x, y);
|
||||||
}
|
}
|
||||||
seat->serial = serial;
|
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;
|
||||||
|
|
||||||
|
#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
|
||||||
|
pointer_button(void *udata, struct wl_pointer *wl_pointer, uint32_t serial,
|
||||||
|
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");
|
||||||
|
if (button == BTN_LEFT){
|
||||||
|
printf("pointer_button (left) %s\n", state_str);
|
||||||
|
}
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pointer_axis(void *udata, struct wl_pointer *wl_pointer,
|
pointer_axis(void *udata, struct wl_pointer *wl_pointer,
|
||||||
CSD_U32 time, CSD_U32 axis, wl_fixed_t fv){
|
uint32_t time, uint32_t axis, wl_fixed_t fv){
|
||||||
int v = wl_fixed_to_int(fv);
|
int v = wl_fixed_to_int(fv);
|
||||||
|
printf("pointer_axis %u,%d\n", axis, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_pointer_listener pointer_listener = {
|
static const struct wl_pointer_listener pointer_listener = {
|
||||||
|
|
@ -166,15 +257,14 @@ static const struct wl_pointer_listener pointer_listener = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
seat_capabilities(void *udata, struct wl_seat *wl_seat, CSD_U32 capabilities){
|
seat_capabilities(void *udata, struct wl_seat *wl_seat, uint32_t capabilities){
|
||||||
CSD_Seat *seat = &ctx.seat;
|
if ((capabilities & WL_SEAT_CAPABILITY_POINTER) && ctx.wl_pointer == 0){
|
||||||
if ((capabilities & WL_SEAT_CAPABILITY_POINTER) && seat->wl_pointer == 0){
|
ctx.wl_pointer = wl_seat_get_pointer(ctx.wl_seat);
|
||||||
seat->wl_pointer = wl_seat_get_pointer(seat->wl_seat);
|
wl_pointer_add_listener(ctx.wl_pointer, &pointer_listener, 0);
|
||||||
wl_pointer_add_listener(seat->wl_pointer, &pointer_listener, 0);
|
|
||||||
}
|
}
|
||||||
else if (!(capabilities & WL_SEAT_CAPABILITY_POINTER) && seat->wl_pointer != 0){
|
else if (!(capabilities & WL_SEAT_CAPABILITY_POINTER) && ctx.wl_pointer != 0){
|
||||||
wl_pointer_release(seat->wl_pointer);
|
wl_pointer_release(ctx.wl_pointer);
|
||||||
seat->wl_pointer = 0;
|
ctx.wl_pointer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,7 +278,8 @@ static const struct wl_seat_listener seat_listener = {
|
||||||
|
|
||||||
static void
|
static void
|
||||||
registry_global(void *udata, struct wl_registry *wl_registry,
|
registry_global(void *udata, struct wl_registry *wl_registry,
|
||||||
CSD_U32 name, const char *interface, CSD_U32 version){
|
uint32_t name, const char *interface,
|
||||||
|
uint32_t version){
|
||||||
if (strcmp(interface, "wl_compositor") == 0){
|
if (strcmp(interface, "wl_compositor") == 0){
|
||||||
ctx.wl_compositor = (struct wl_compositor*)
|
ctx.wl_compositor = (struct wl_compositor*)
|
||||||
wl_registry_bind(wl_registry, name, &wl_compositor_interface,
|
wl_registry_bind(wl_registry, name, &wl_compositor_interface,
|
||||||
|
|
@ -215,12 +306,9 @@ registry_global(void *udata, struct wl_registry *wl_registry,
|
||||||
CSD_Min(version, 2));
|
CSD_Min(version, 2));
|
||||||
}
|
}
|
||||||
else if (strcmp(interface, "wl_seat") == 0){
|
else if (strcmp(interface, "wl_seat") == 0){
|
||||||
CSD_Seat *seat = &ctx.seat;
|
ctx.wl_seat = wl_registry_bind(ctx.wl_registry, name, &wl_seat_interface, 3);
|
||||||
if (seat->wl_seat == 0){
|
wl_seat_add_listener(ctx.wl_seat, &seat_listener, 0);
|
||||||
seat->wl_seat = wl_registry_bind(ctx.wl_registry, name, &wl_seat_interface, 3);
|
ctx.cursor_surface = wl_compositor_create_surface(ctx.wl_compositor);
|
||||||
wl_seat_add_listener(seat->wl_seat, &seat_listener, 0);
|
|
||||||
seat->cursor_surface = wl_compositor_create_surface(ctx.wl_compositor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -529,12 +617,9 @@ int main(){
|
||||||
window->dim[1] + window->csd_dim[1]);
|
window->dim[1] + window->csd_dim[1]);
|
||||||
wl_egl_window_resize(ctx.main_wl_egl_window,
|
wl_egl_window_resize(ctx.main_wl_egl_window,
|
||||||
window->dim[0], window->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;
|
||||||
CSD_Seat *seat = &ctx.seat;
|
|
||||||
seat->cursor_shape = CSD_CursorShape_Pointer;
|
|
||||||
csd_gtk_update_and_render();
|
csd_gtk_update_and_render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -559,18 +644,17 @@ int main(){
|
||||||
|
|
||||||
/* commit new cursor */
|
/* commit new cursor */
|
||||||
{
|
{
|
||||||
CSD_Seat *seat = &ctx.seat;
|
|
||||||
CSD_Window *window = &ctx.window;
|
CSD_Window *window = &ctx.window;
|
||||||
struct wl_cursor *cursor = ctx.wl_cursors[seat->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];
|
||||||
struct wl_buffer *cursor_buffer = wl_cursor_image_get_buffer(cursor_image);
|
struct wl_buffer *cursor_buffer = wl_cursor_image_get_buffer(cursor_image);
|
||||||
wl_surface_set_buffer_scale(seat->cursor_surface, 1);
|
wl_surface_set_buffer_scale(ctx.cursor_surface, 1);
|
||||||
wl_surface_attach(seat->cursor_surface, cursor_buffer, 0, 0);
|
wl_surface_attach(ctx.cursor_surface, cursor_buffer, 0, 0);
|
||||||
wl_surface_damage_buffer(seat->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(seat->cursor_surface);
|
wl_surface_commit(ctx.cursor_surface);
|
||||||
wl_pointer_set_cursor(seat->wl_pointer, seat->serial, seat->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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1028,37 +1112,44 @@ 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){
|
||||||
CSD_Seat *seat = &ctx.seat;
|
|
||||||
CSD_Window *window = &ctx.window;
|
CSD_Window *window = &ctx.window;
|
||||||
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
|
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
|
||||||
|
|
||||||
/* determine cursor location information */
|
if (window->control_flags & CSD_WindowControlFlag_Resize){
|
||||||
enum{
|
static const CSD_CursorShape cursor_box[] = {
|
||||||
LOCATION_NULL, LOCATION_SHADOW, LOCATION_TITLEBAR,
|
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,
|
||||||
};
|
};
|
||||||
CSD_U32 cursor_loc = LOCATION_NULL;
|
|
||||||
CSD_S32 cursor_shadow_loc = 0;
|
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,
|
||||||
CSD_S32 l = (seat->hover_p[0] < 0);
|
XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT,
|
||||||
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]);
|
int l = (ctx.hover_p[0] < 0);
|
||||||
cursor_shadow_loc = 3*(b - t) + (r - l);
|
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;
|
||||||
|
if (loc != 0){
|
||||||
|
xdg_toplevel_resize(window->main_xdg_toplevel, ctx.wl_seat,
|
||||||
|
window->serial, xedge_box[4 + loc]);
|
||||||
}
|
}
|
||||||
if (cursor_shadow_loc != 0){
|
else if (ctx.hover_p[1] < 0){
|
||||||
cursor_loc = LOCATION_SHADOW;
|
xdg_toplevel_move(window->main_xdg_toplevel, ctx.wl_seat, window->serial);
|
||||||
}
|
}
|
||||||
else if (seat->hover_p[1] < 0){
|
|
||||||
cursor_loc = LOCATION_TITLEBAR;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* draw shadow */
|
|
||||||
{
|
{
|
||||||
CSD_SubSurface *subsurface = >k_window->shadow;
|
CSD_SubSurface *subsurface = >k_window->shadow;
|
||||||
|
|
||||||
CSD_S32 shadow_dim[2];
|
int32_t shadow_dim[2];
|
||||||
shadow_dim[0] = window->dim[0] + 2*SHADOW_MARGIN;
|
shadow_dim[0] = window->dim[0] + 2*SHADOW_MARGIN;
|
||||||
shadow_dim[1] = (window->dim[1] + 2*SHADOW_MARGIN +
|
shadow_dim[1] = (window->dim[1] + 2*SHADOW_MARGIN +
|
||||||
window->csd_frame.border[1][0]);
|
window->csd_frame.border[1][0]);
|
||||||
|
|
@ -1098,30 +1189,10 @@ csd_gtk_update_and_render(void){
|
||||||
csd_subsurface_commit(subsurface);
|
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;
|
CSD_SubSurface *subsurface = >k_window->titlebar;
|
||||||
|
|
||||||
CSD_S32 title_dim[2];
|
int32_t title_dim[2];
|
||||||
title_dim[0] = window->dim[0];
|
title_dim[0] = window->dim[0];
|
||||||
title_dim[1] = window->csd_frame.border[1][0];
|
title_dim[1] = window->csd_frame.border[1][0];
|
||||||
|
|
||||||
|
|
@ -1156,14 +1227,14 @@ csd_gtk_update_and_render(void){
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
CSD_S32 stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, title_dim[0]);
|
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, title_dim[0]);
|
||||||
cairo_surface_t *cr_surface =
|
cairo_surface_t *cr_surface =
|
||||||
cairo_image_surface_create_for_data(subsurface->data, CAIRO_FORMAT_ARGB32,
|
cairo_image_surface_create_for_data(subsurface->data, CAIRO_FORMAT_ARGB32,
|
||||||
title_dim[0], title_dim[1], stride);
|
title_dim[0], title_dim[1], stride);
|
||||||
cairo_t *cr = cairo_create(cr_surface);
|
cairo_t *cr = cairo_create(cr_surface);
|
||||||
cairo_surface_set_device_scale(cr_surface, 1, 1);
|
cairo_surface_set_device_scale(cr_surface, 1, 1);
|
||||||
|
|
||||||
/* draw background */
|
/* background */
|
||||||
{
|
{
|
||||||
GtkAllocation allocation;
|
GtkAllocation allocation;
|
||||||
gtk_widget_get_allocation(GTK_WIDGET(gtk_window->header), &allocation);
|
gtk_widget_get_allocation(GTK_WIDGET(gtk_window->header), &allocation);
|
||||||
|
|
@ -1173,7 +1244,7 @@ csd_gtk_update_and_render(void){
|
||||||
allocation.width, allocation.height);
|
allocation.width, allocation.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* draw title */
|
/* title */
|
||||||
{
|
{
|
||||||
GtkWidget *label_title =
|
GtkWidget *label_title =
|
||||||
csd_gtk__widget_from_name(gtk_window->header, "label.title:");
|
csd_gtk__widget_from_name(gtk_window->header, "label.title:");
|
||||||
|
|
@ -1191,63 +1262,72 @@ csd_gtk_update_and_render(void){
|
||||||
cairo_surface_destroy(cr_label_surface);
|
cairo_surface_destroy(cr_label_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* draw buttons */
|
/* buttons */
|
||||||
for (CSD_U32 i = 1; i < HEADER_BUTTON_COUNT; i += 1){
|
uint32_t buttons[3] = {0};
|
||||||
if (header_button_active[i]){
|
int button_count = 0;
|
||||||
|
if (window->control_flags & CSD_WindowControlFlag_Min){
|
||||||
|
buttons[button_count] = 0;
|
||||||
|
button_count += 1;
|
||||||
|
}
|
||||||
|
if ((window->control_flags & CSD_WindowControlFlag_Max) &&
|
||||||
|
(window->control_flags & CSD_WindowControlFlag_Resize)){
|
||||||
|
buttons[button_count] = 1;
|
||||||
|
button_count += 1;
|
||||||
|
}
|
||||||
|
if (window->control_flags & CSD_WindowControlFlag_Close){
|
||||||
|
buttons[button_count] = 2;
|
||||||
|
button_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < button_count; i += 1){
|
||||||
|
CSD_U32 button_code = buttons[i];
|
||||||
|
|
||||||
|
char *button_name = "";
|
||||||
char *icon_name = "";
|
char *icon_name = "";
|
||||||
switch (i){
|
switch (button_code){
|
||||||
case HEADER_BUTTON_MIN: {
|
case 0: {
|
||||||
|
button_name = ".minimize";
|
||||||
icon_name = "window-minimize-symbolic";
|
icon_name = "window-minimize-symbolic";
|
||||||
}break;
|
}break;
|
||||||
case HEADER_BUTTON_MAX: {
|
case 1: {
|
||||||
|
button_name = ".maximize";
|
||||||
icon_name = ((window->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 HEADER_BUTTON_CLOSE: {
|
case 2: {
|
||||||
|
button_name = ".close";
|
||||||
icon_name = "window-close-symbolic";
|
icon_name = "window-close-symbolic";
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *widget =
|
GtkWidget *button_widget =
|
||||||
csd_gtk__widget_from_name(gtk_window->header, header_button_name[i]);
|
csd_gtk__widget_from_name(gtk_window->header, button_name);
|
||||||
|
|
||||||
if (widget != 0){
|
if (button_widget != 0){
|
||||||
/* layout */
|
GtkStyleContext *style = gtk_widget_get_style_context(button_widget);
|
||||||
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];
|
|
||||||
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;
|
|
||||||
is_hovered = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* change style based on window state and focus */
|
/* change style based on window state and focus */
|
||||||
GtkStyleContext *style = gtk_widget_get_style_context(widget);
|
|
||||||
GtkStateFlags style_state = 0;
|
GtkStateFlags style_state = 0;
|
||||||
if (!(window->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 (is_hovered){
|
if (gtk_window->hover_button_code == button_code){
|
||||||
style_state |= GTK_STATE_FLAG_PRELIGHT;
|
style_state |= GTK_STATE_FLAG_PRELIGHT;
|
||||||
if (i == gtk_window->active_header_button){
|
if (gtk_window->active_button_code == button_code){
|
||||||
style_state |= GTK_STATE_FLAG_ACTIVE;
|
style_state |= GTK_STATE_FLAG_ACTIVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* background */
|
/* background */
|
||||||
|
GtkAllocation allocation;
|
||||||
|
gtk_widget_get_clip(button_widget, &allocation);
|
||||||
|
|
||||||
gtk_style_context_save(style);
|
gtk_style_context_save(style);
|
||||||
gtk_style_context_set_state(style, style_state);
|
gtk_style_context_set_state(style, style_state);
|
||||||
gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
|
gtk_render_background(style, cr, allocation.x, allocation.y,
|
||||||
gtk_render_frame(style, cr, rect.x, rect.y, rect.width, rect.height);
|
allocation.width, allocation.height);
|
||||||
|
gtk_render_frame(style, cr, allocation.x, allocation.y,
|
||||||
|
allocation.width, allocation.height);
|
||||||
gtk_style_context_restore(style);
|
gtk_style_context_restore(style);
|
||||||
|
|
||||||
/* get scale */
|
/* get scale */
|
||||||
|
|
@ -1256,7 +1336,7 @@ csd_gtk_update_and_render(void){
|
||||||
int scale = (sx + sy)/2.0;
|
int scale = (sx + sy)/2.0;
|
||||||
|
|
||||||
/* get original icon dimensions */
|
/* get original icon dimensions */
|
||||||
GtkWidget *icon_widget = gtk_bin_get_child(GTK_BIN(widget));
|
GtkWidget *icon_widget = gtk_bin_get_child(GTK_BIN(button_widget));
|
||||||
|
|
||||||
/* icon info */
|
/* icon info */
|
||||||
gint icon_width, icon_height;
|
gint icon_width, icon_height;
|
||||||
|
|
@ -1285,30 +1365,37 @@ csd_gtk_update_and_render(void){
|
||||||
width = CSD_ClampBot(width, icon_width);
|
width = CSD_ClampBot(width, icon_width);
|
||||||
height = CSD_ClampBot(height, icon_height);
|
height = CSD_ClampBot(height, icon_height);
|
||||||
|
|
||||||
|
gint left = 0;
|
||||||
|
gint top = 0;
|
||||||
|
gint right = 0;
|
||||||
|
gint bottom = 0;
|
||||||
|
|
||||||
GtkBorder border;
|
GtkBorder border;
|
||||||
gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border);
|
gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border);
|
||||||
|
left += border.left;
|
||||||
|
right += border.right;
|
||||||
|
top += border.top;
|
||||||
|
bottom += border.bottom;
|
||||||
|
|
||||||
GtkBorder padding;
|
GtkBorder padding;
|
||||||
gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
|
gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
|
||||||
|
left += padding.left;
|
||||||
gint left = border.left + padding.left;
|
right += padding.right;
|
||||||
gint right = border.right + padding.right;
|
top += padding.top;
|
||||||
gint top = border.top + padding.top;
|
bottom += padding.bottom;
|
||||||
gint bottom = border.bottom + padding.bottom;
|
|
||||||
|
|
||||||
width += left + right;
|
width += left + right;
|
||||||
height += top + bottom;
|
height += top + bottom;
|
||||||
|
|
||||||
gtk_render_icon_surface(gtk_widget_get_style_context(icon_widget),
|
gtk_render_icon_surface(gtk_widget_get_style_context(icon_widget),
|
||||||
cr, icon_surface,
|
cr, icon_surface,
|
||||||
rect.x + (width - icon_width)/2,
|
allocation.x + (width - icon_width)/2,
|
||||||
rect.y + (height - icon_height)/2);
|
allocation.y + (height - icon_height)/2);
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
cairo_surface_destroy(icon_surface);
|
cairo_surface_destroy(icon_surface);
|
||||||
g_object_unref(icon_pixbuf);
|
g_object_unref(icon_pixbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
cairo_destroy(cr);
|
cairo_destroy(cr);
|
||||||
cairo_surface_destroy(cr_surface);
|
cairo_surface_destroy(cr_surface);
|
||||||
|
|
@ -1317,62 +1404,6 @@ csd_gtk_update_and_render(void){
|
||||||
csd_subsurface_set_position(subsurface, 0, -window->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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* process events */
|
|
||||||
if (ctx.has_event){
|
|
||||||
|
|
||||||
/* handle left-button press */
|
|
||||||
if (ctx.event_button == BTN_LEFT &&
|
|
||||||
ctx.event_button_state == 1){
|
|
||||||
switch (cursor_loc){
|
|
||||||
default: case LOCATION_NULL: break;
|
|
||||||
|
|
||||||
case LOCATION_SHADOW: {
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
xdg_toplevel_resize(window->main_xdg_toplevel, seat->wl_seat,
|
|
||||||
seat->serial, xedge_box[4 + cursor_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);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
gtk_window->active_header_button = header_button_hover;
|
|
||||||
}
|
|
||||||
ctx.has_event = 0;
|
|
||||||
}break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* handle left-button release */
|
|
||||||
if (ctx.event_button == BTN_LEFT &&
|
|
||||||
ctx.event_button_state == 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 = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set cursor shape */
|
|
||||||
if (window->control_flags & CSD_WindowControlFlag_Resize){
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
seat->cursor_shape = cursor_box[4 + cursor_shadow_loc];
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
seat->cursor_shape = CSD_CursorShape_Pointer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cairo shadow rendering */
|
/* cairo shadow rendering */
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ typedef struct CSD_Config{
|
||||||
} CSD_Config;
|
} CSD_Config;
|
||||||
|
|
||||||
typedef struct CSD_Frame{
|
typedef struct CSD_Frame{
|
||||||
CSD_S32 border[2][2];
|
CSD_S32 border[2][2]; // [0][]:x [1][]:y [][0]:min [][1]:max
|
||||||
CSD_S32 minbox[2];
|
CSD_S32 minbox[2];
|
||||||
} CSD_Frame;
|
} CSD_Frame;
|
||||||
|
|
||||||
|
|
@ -111,6 +111,7 @@ typedef struct CSD_Window{
|
||||||
|
|
||||||
CSD_Config config;
|
CSD_Config config;
|
||||||
CSD_Config config_staged;
|
CSD_Config config_staged;
|
||||||
|
CSD_U32 serial;
|
||||||
|
|
||||||
CSD_Frame csd_frame;
|
CSD_Frame csd_frame;
|
||||||
CSD_S32 csd_dim[2];
|
CSD_S32 csd_dim[2];
|
||||||
|
|
@ -119,18 +120,6 @@ typedef struct CSD_Window{
|
||||||
CSD_S32 dim[2];
|
CSD_S32 dim[2];
|
||||||
} CSD_Window;
|
} 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 */
|
/* csd helpers */
|
||||||
|
|
||||||
static CSD_SubSurface csd_subsurface_new(void);
|
static CSD_SubSurface csd_subsurface_new(void);
|
||||||
|
|
@ -167,14 +156,17 @@ typedef struct CSD_GTK_Ctx{
|
||||||
} CSD_GTK_Ctx;
|
} CSD_GTK_Ctx;
|
||||||
|
|
||||||
typedef struct CSD_GTK_Window{
|
typedef struct CSD_GTK_Window{
|
||||||
|
CSD_U32 button;
|
||||||
|
CSD_S32 double_click_time_ms;
|
||||||
|
|
||||||
CSD_SubSurface titlebar;
|
CSD_SubSurface titlebar;
|
||||||
CSD_SubSurface shadow;
|
CSD_SubSurface shadow;
|
||||||
|
|
||||||
GtkWidget *window;
|
GtkWidget *window;
|
||||||
GtkWidget *header;
|
GtkWidget *header;
|
||||||
|
|
||||||
CSD_S32 double_click_time_ms;
|
CSD_U32 hover_button_code;
|
||||||
CSD_U32 active_header_button;
|
CSD_U32 active_button_code;
|
||||||
} CSD_GTK_Window;
|
} CSD_GTK_Window;
|
||||||
|
|
||||||
/* csd gtk implementation */
|
/* csd gtk implementation */
|
||||||
|
|
@ -184,6 +176,14 @@ static void csd_gtk_window_init(void);
|
||||||
static CSD_Frame csd_gtk_calculate_frame(void);
|
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);
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
|
||||||
|
|
@ -196,13 +196,9 @@ static void csd_gtk_render_shadow(cairo_t *cr, cairo_surface_t *surface,
|
||||||
/* example */
|
/* example */
|
||||||
|
|
||||||
typedef struct Ctx{
|
typedef struct Ctx{
|
||||||
/* the rest */
|
/* "application variables" */
|
||||||
CSD_B32 close_signal;
|
CSD_B32 close_signal;
|
||||||
|
|
||||||
CSD_B32 has_event;
|
|
||||||
CSD_U32 event_button;
|
|
||||||
CSD_U32 event_button_state;
|
|
||||||
|
|
||||||
/* globals: desktop settings */
|
/* globals: desktop settings */
|
||||||
CSD_ColorScheme color_scheme;
|
CSD_ColorScheme color_scheme;
|
||||||
CSD_CursorTheme cursor_theme;
|
CSD_CursorTheme cursor_theme;
|
||||||
|
|
@ -226,8 +222,15 @@ typedef struct Ctx{
|
||||||
/* globals: gtk */
|
/* globals: gtk */
|
||||||
CSD_GTK_Ctx gtk_ctx;
|
CSD_GTK_Ctx gtk_ctx;
|
||||||
|
|
||||||
/* per-seat */
|
/* per-seat: wayland */
|
||||||
CSD_Seat seat;
|
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-window: egl */
|
/* per-window: egl */
|
||||||
struct wl_egl_window *main_wl_egl_window;
|
struct wl_egl_window *main_wl_egl_window;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue