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 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 = {
|
||||
shm_format
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -83,78 +83,169 @@ 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,
|
||||
pointer_enter(void *udata, struct wl_pointer *wl_pointer, uint32_t 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;
|
||||
|
||||
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){
|
||||
// surface_off = {0,0}
|
||||
printf("pointer_enter (main) %d,%d\n", x, y);
|
||||
}
|
||||
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){
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
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
|
||||
}
|
||||
|
||||
static void
|
||||
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,
|
||||
CSD_U32 time, wl_fixed_t fx, wl_fixed_t fy){
|
||||
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;
|
||||
|
||||
CSD_Seat *seat = &ctx.seat;
|
||||
|
||||
CSD_S32 surface_off[2] = {0};
|
||||
if (seat->hover_surface == window->main_wl_surface){
|
||||
// surface_off = {0,0}
|
||||
if (surface == window->main_wl_surface){
|
||||
printf("pointer_leave (main)\n");
|
||||
}
|
||||
else if (seat->hover_surface == gtk_window->titlebar.wl_surface){
|
||||
memcpy(surface_off, gtk_window->titlebar.p, sizeof(surface_off));
|
||||
else if (surface == gtk_window->titlebar.wl_surface){
|
||||
printf("pointer_leave (titlebar)\n");
|
||||
}
|
||||
else if (seat->hover_surface == gtk_window->shadow.wl_surface){
|
||||
memcpy(surface_off, gtk_window->shadow.p, sizeof(surface_off));
|
||||
else if (surface == gtk_window->shadow.wl_surface){
|
||||
printf("pointer_leave (shadow)\n");
|
||||
}
|
||||
|
||||
seat->hover_p[0] = surface_off[0] + wl_fixed_to_int(fx);
|
||||
seat->hover_p[1] = surface_off[1] + wl_fixed_to_int(fy);
|
||||
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
|
||||
}
|
||||
|
||||
static void
|
||||
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;
|
||||
pointer_motion(void *udata, struct wl_pointer *wl_pointer, uint32_t time,
|
||||
wl_fixed_t fx, wl_fixed_t fy){
|
||||
CSD_Window *window = &ctx.window;
|
||||
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
|
||||
{
|
||||
ctx.has_event = 1;
|
||||
ctx.event_button = button;
|
||||
ctx.event_button_state = state;
|
||||
|
||||
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);
|
||||
}
|
||||
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
|
||||
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);
|
||||
printf("pointer_axis %u,%d\n", axis, v);
|
||||
}
|
||||
|
||||
static const struct wl_pointer_listener pointer_listener = {
|
||||
|
|
@ -166,15 +257,14 @@ static const struct wl_pointer_listener pointer_listener = {
|
|||
};
|
||||
|
||||
static void
|
||||
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);
|
||||
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);
|
||||
}
|
||||
else if (!(capabilities & WL_SEAT_CAPABILITY_POINTER) && seat->wl_pointer != 0){
|
||||
wl_pointer_release(seat->wl_pointer);
|
||||
seat->wl_pointer = 0;
|
||||
else if (!(capabilities & WL_SEAT_CAPABILITY_POINTER) && ctx.wl_pointer != 0){
|
||||
wl_pointer_release(ctx.wl_pointer);
|
||||
ctx.wl_pointer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -188,7 +278,8 @@ static const struct wl_seat_listener seat_listener = {
|
|||
|
||||
static void
|
||||
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){
|
||||
ctx.wl_compositor = (struct wl_compositor*)
|
||||
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));
|
||||
}
|
||||
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);
|
||||
wl_seat_add_listener(seat->wl_seat, &seat_listener, 0);
|
||||
seat->cursor_surface = wl_compositor_create_surface(ctx.wl_compositor);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -529,12 +617,9 @@ 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 */
|
||||
{
|
||||
CSD_Seat *seat = &ctx.seat;
|
||||
seat->cursor_shape = CSD_CursorShape_Pointer;
|
||||
ctx.cursor_shape = CSD_CursorShape_Pointer;
|
||||
csd_gtk_update_and_render();
|
||||
}
|
||||
|
||||
|
|
@ -559,18 +644,17 @@ 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];
|
||||
struct wl_cursor *cursor = ctx.wl_cursors[ctx.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(seat->cursor_surface, 1);
|
||||
wl_surface_attach(seat->cursor_surface, cursor_buffer, 0, 0);
|
||||
wl_surface_damage_buffer(seat->cursor_surface, 0, 0,
|
||||
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,
|
||||
cursor_image->width, cursor_image->height);
|
||||
wl_surface_commit(seat->cursor_surface);
|
||||
wl_pointer_set_cursor(seat->wl_pointer, seat->serial, seat->cursor_surface,
|
||||
wl_surface_commit(ctx.cursor_surface);
|
||||
wl_pointer_set_cursor(ctx.wl_pointer, window->serial, ctx.cursor_surface,
|
||||
cursor_image->hotspot_x, cursor_image->hotspot_y);
|
||||
}
|
||||
}
|
||||
|
|
@ -1028,37 +1112,44 @@ 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;
|
||||
|
||||
/* determine cursor location information */
|
||||
enum{
|
||||
LOCATION_NULL, LOCATION_SHADOW, LOCATION_TITLEBAR,
|
||||
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,
|
||||
};
|
||||
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);
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
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;
|
||||
if (loc != 0){
|
||||
xdg_toplevel_resize(window->main_xdg_toplevel, ctx.wl_seat,
|
||||
window->serial, xedge_box[4 + loc]);
|
||||
}
|
||||
if (cursor_shadow_loc != 0){
|
||||
cursor_loc = LOCATION_SHADOW;
|
||||
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){
|
||||
cursor_loc = LOCATION_TITLEBAR;
|
||||
}
|
||||
}
|
||||
|
||||
/* draw 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[1] = (window->dim[1] + 2*SHADOW_MARGIN +
|
||||
window->csd_frame.border[1][0]);
|
||||
|
|
@ -1098,30 +1189,10 @@ 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;
|
||||
|
||||
CSD_S32 title_dim[2];
|
||||
int32_t title_dim[2];
|
||||
title_dim[0] = window->dim[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_image_surface_create_for_data(subsurface->data, CAIRO_FORMAT_ARGB32,
|
||||
title_dim[0], title_dim[1], stride);
|
||||
cairo_t *cr = cairo_create(cr_surface);
|
||||
cairo_surface_set_device_scale(cr_surface, 1, 1);
|
||||
|
||||
/* draw background */
|
||||
/* background */
|
||||
{
|
||||
GtkAllocation 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);
|
||||
}
|
||||
|
||||
/* draw title */
|
||||
/* title */
|
||||
{
|
||||
GtkWidget *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);
|
||||
}
|
||||
|
||||
/* draw buttons */
|
||||
for (CSD_U32 i = 1; i < HEADER_BUTTON_COUNT; i += 1){
|
||||
if (header_button_active[i]){
|
||||
/* buttons */
|
||||
uint32_t buttons[3] = {0};
|
||||
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 = "";
|
||||
switch (i){
|
||||
case HEADER_BUTTON_MIN: {
|
||||
switch (button_code){
|
||||
case 0: {
|
||||
button_name = ".minimize";
|
||||
icon_name = "window-minimize-symbolic";
|
||||
}break;
|
||||
case HEADER_BUTTON_MAX: {
|
||||
case 1: {
|
||||
button_name = ".maximize";
|
||||
icon_name = ((window->config.flags & CSD_WindowFlag_IsMax) ?
|
||||
"window-restore-symbolic" : "window-maximize-symbolic");
|
||||
}break;
|
||||
case HEADER_BUTTON_CLOSE: {
|
||||
case 2: {
|
||||
button_name = ".close";
|
||||
icon_name = "window-close-symbolic";
|
||||
}break;
|
||||
}
|
||||
|
||||
GtkWidget *widget =
|
||||
csd_gtk__widget_from_name(gtk_window->header, header_button_name[i]);
|
||||
GtkWidget *button_widget =
|
||||
csd_gtk__widget_from_name(gtk_window->header, button_name);
|
||||
|
||||
if (widget != 0){
|
||||
/* layout */
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (button_widget != 0){
|
||||
GtkStyleContext *style = gtk_widget_get_style_context(button_widget);
|
||||
|
||||
/* change style based on window state and focus */
|
||||
GtkStyleContext *style = gtk_widget_get_style_context(widget);
|
||||
GtkStateFlags style_state = 0;
|
||||
if (!(window->config.flags & CSD_WindowFlag_IsActivated)){
|
||||
style_state |= GTK_STATE_FLAG_BACKDROP;
|
||||
}
|
||||
if (is_hovered){
|
||||
if (gtk_window->hover_button_code == button_code){
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* background */
|
||||
GtkAllocation allocation;
|
||||
gtk_widget_get_clip(button_widget, &allocation);
|
||||
|
||||
gtk_style_context_save(style);
|
||||
gtk_style_context_set_state(style, style_state);
|
||||
gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
|
||||
gtk_render_frame(style, cr, rect.x, rect.y, rect.width, rect.height);
|
||||
gtk_render_background(style, cr, allocation.x, allocation.y,
|
||||
allocation.width, allocation.height);
|
||||
gtk_render_frame(style, cr, allocation.x, allocation.y,
|
||||
allocation.width, allocation.height);
|
||||
gtk_style_context_restore(style);
|
||||
|
||||
/* get scale */
|
||||
|
|
@ -1256,7 +1336,7 @@ csd_gtk_update_and_render(void){
|
|||
int scale = (sx + sy)/2.0;
|
||||
|
||||
/* 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 */
|
||||
gint icon_width, icon_height;
|
||||
|
|
@ -1285,30 +1365,37 @@ csd_gtk_update_and_render(void){
|
|||
width = CSD_ClampBot(width, icon_width);
|
||||
height = CSD_ClampBot(height, icon_height);
|
||||
|
||||
gint left = 0;
|
||||
gint top = 0;
|
||||
gint right = 0;
|
||||
gint bottom = 0;
|
||||
|
||||
GtkBorder 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;
|
||||
gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
|
||||
|
||||
gint left = border.left + padding.left;
|
||||
gint right = border.right + padding.right;
|
||||
gint top = border.top + padding.top;
|
||||
gint bottom = border.bottom + padding.bottom;
|
||||
left += padding.left;
|
||||
right += padding.right;
|
||||
top += padding.top;
|
||||
bottom += padding.bottom;
|
||||
|
||||
width += left + right;
|
||||
height += top + bottom;
|
||||
|
||||
gtk_render_icon_surface(gtk_widget_get_style_context(icon_widget),
|
||||
cr, icon_surface,
|
||||
rect.x + (width - icon_width)/2,
|
||||
rect.y + (height - icon_height)/2);
|
||||
allocation.x + (width - icon_width)/2,
|
||||
allocation.y + (height - icon_height)/2);
|
||||
cairo_paint(cr);
|
||||
cairo_surface_destroy(icon_surface);
|
||||
g_object_unref(icon_pixbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cairo_destroy(cr);
|
||||
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_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 */
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ typedef struct CSD_Config{
|
|||
} CSD_Config;
|
||||
|
||||
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_Frame;
|
||||
|
||||
|
|
@ -111,6 +111,7 @@ typedef struct CSD_Window{
|
|||
|
||||
CSD_Config config;
|
||||
CSD_Config config_staged;
|
||||
CSD_U32 serial;
|
||||
|
||||
CSD_Frame csd_frame;
|
||||
CSD_S32 csd_dim[2];
|
||||
|
|
@ -119,18 +120,6 @@ 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);
|
||||
|
|
@ -167,14 +156,17 @@ 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;
|
||||
CSD_SubSurface shadow;
|
||||
|
||||
GtkWidget *window;
|
||||
GtkWidget *header;
|
||||
|
||||
CSD_S32 double_click_time_ms;
|
||||
CSD_U32 active_header_button;
|
||||
CSD_U32 hover_button_code;
|
||||
CSD_U32 active_button_code;
|
||||
} CSD_GTK_Window;
|
||||
|
||||
/* csd gtk implementation */
|
||||
|
|
@ -184,6 +176,14 @@ 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,13 +196,9 @@ static void csd_gtk_render_shadow(cairo_t *cr, cairo_surface_t *surface,
|
|||
/* example */
|
||||
|
||||
typedef struct Ctx{
|
||||
/* the rest */
|
||||
/* "application variables" */
|
||||
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;
|
||||
|
|
@ -226,8 +222,15 @@ typedef struct Ctx{
|
|||
/* globals: gtk */
|
||||
CSD_GTK_Ctx gtk_ctx;
|
||||
|
||||
/* per-seat */
|
||||
CSD_Seat seat;
|
||||
/* 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-window: egl */
|
||||
struct wl_egl_window *main_wl_egl_window;
|
||||
|
|
|
|||
Loading…
Reference in New Issue