diff --git a/digesting_libdecor.c b/digesting_libdecor.c index ee01378..0350941 100755 --- a/digesting_libdecor.c +++ b/digesting_libdecor.c @@ -91,14 +91,69 @@ GL_FUNCS_XLIST(X) static Ctx ctx = {0}; +static void +xdg_wm_base_ping(void *user_data, struct xdg_wm_base *xdg_wm_base, uint32_t serial){ + xdg_wm_base_pong(xdg_wm_base, serial); +} + +const struct xdg_wm_base_listener xdg_wm_base_listener = { xdg_wm_base_ping, }; + +static void +shm_format(void *user_data, struct wl_shm *wl_shm, uint32_t format){ + if (format == WL_SHM_FORMAT_ARGB8888){ + ctx.has_argb = true; + } +} + +const struct wl_shm_listener shm_listener = { shm_format }; + +static void +output_geometry(void *data, struct wl_output *wl_output, + int32_t x, int32_t y, + int32_t physical_width, int32_t physical_height, + int32_t subpixel, const char *make, const char *model, + int32_t transform){} + +static void +output_mode(void *data, struct wl_output *wl_output, + uint32_t flags, int32_t width, int32_t height, + int32_t refresh){} + +static void +output_done(void *data, struct wl_output *wl_output){ + struct output *output = data; + struct seat *seat; + + if (ctx.decoration_type != DECORATION_TYPE_NONE){ + redraw_scale(&ctx.shadow); + } + wl_list_for_each(seat, &ctx.seat_list, link){ + if (update_local_cursor(seat)){ + send_cursor(seat); + } + } +} + +static void +output_scale(void *data, struct wl_output *wl_output, int32_t factor){ + struct output *output = data; + output->scale = factor; +} + +const struct wl_output_listener output_listener = { + output_geometry, + output_mode, + output_done, + output_scale +}; + static void wlevent__wl_registry_global(void *data, struct wl_registry *wl_registry, 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, - MIN(version, 4)); + wl_registry_bind(wl_registry, name, &wl_compositor_interface, MIN(version, 4)); } else if (!strcmp(interface, xdg_wm_base_interface.name)){ ctx.xdg_wm_base = wl_registry_bind(ctx.wl_registry, name, &xdg_wm_base_interface, MIN(version, 2)); @@ -153,7 +208,7 @@ wlevent__wl_registry_global(void *data, struct wl_registry *wl_registry, wl_list_insert(&ctx.output_list, &output->link); output->id = name; output->wl_output = wl_registry_bind(ctx.wl_registry, name, &wl_output_interface, MIN(version, 3)); - wl_proxy_set_tag((struct wl_proxy *)output->wl_output, &libdecor_gtk_proxy_tag); + wl_proxy_set_tag((struct wl_proxy*)output->wl_output, &libdecor_gtk_proxy_tag); wl_output_add_listener(output->wl_output, &output_listener, output); } } @@ -175,17 +230,6 @@ const struct wl_registry_listener wl_registry_listener = { wlevent__wl_registry_global_remove, }; -static void -shm_format(void *user_data, struct wl_shm *wl_shm, uint32_t format){ - if (format == WL_SHM_FORMAT_ARGB8888){ - ctx.has_argb = true; - } -} - -const struct wl_shm_listener shm_listener = { - shm_format -}; - static void init_wl_display_callback(void *user_data, struct wl_callback *callback, uint32_t time){ struct libdecor *context = user_data; @@ -547,12 +591,43 @@ int main(){ exit_loop = 1; } for (;!exit_loop;){ - /* (libdecor.h) - ** " Dispatch events. This function should be called when data is available on - ** the file descriptor returned by libdecor_get_fd(). If timeout is zero, this - ** function will never block. " - */ - libdecor_dispatch(0); + for (;g_main_context_iteration(0, 0);){} + + { + struct pollfd fds[1] = {0}; + + /* register fds[0] ~ wayland events */ + bool wayland_started_read = false; + bool wayland_did_read = false; + { + fds[0].fd = -1; + + wl_display_dispatch_pending(ctx.wl_display); + wayland_started_read = (wl_display_prepare_read(ctx.wl_display) != -1); + if (wayland_started_read){ + fds[0].fd = wl_display_get_fd(ctx.wl_display); + fds[0].events = POLLIN; + wl_display_flush(ctx.wl_display); + } + } + + /* poll and handle events */ + int ret = poll(fds, ARRAY_LENGTH(fds), 0); + if (ret > 0){ + + /* handle fds[0] ~ wayland events */ + if (fds[0].revents & POLLIN){ + wayland_did_read = true; + wl_display_read_events(ctx.wl_display); + wl_display_dispatch_pending(ctx.wl_display); + } + } + + /* wayland event read cleanup */ + if (wayland_started_read && !wayland_did_read){ + wl_display_cancel_read(ctx.wl_display); + } + } if (ctx.close_signal){ exit_loop = 1; @@ -1099,20 +1174,6 @@ libdecor_frame_commit(int w, int h, struct libdecor_configuration *configuration } } -static void -xdg_wm_base_ping(void *user_data, struct xdg_wm_base *xdg_wm_base, uint32_t serial){ - xdg_wm_base_pong(xdg_wm_base, serial); -} - -const struct xdg_wm_base_listener xdg_wm_base_listener = { - xdg_wm_base_ping, -}; - -int -libdecor_dispatch(int timeout){ - return libdecor_plugin_gtk_dispatch(timeout); -} - void cleanup(void){ { @@ -1612,55 +1673,6 @@ own_proxy(void *proxy){ return(result); } -static void buffer_free(struct buffer *buffer); - -static void draw_border_component(struct border_component *border_component); - -static void -send_cursor(struct seat *seat); - -static bool -update_local_cursor(struct seat *seat); - -static int -libdecor_plugin_gtk_dispatch(int timeout){ - struct wl_display *wl_display = ctx.wl_display; - struct pollfd fds[1]; - int ret; - int dispatch_count = 0; - - while (g_main_context_iteration(NULL, FALSE)); - - while (wl_display_prepare_read(wl_display) != 0) - dispatch_count += wl_display_dispatch_pending(wl_display); - - if (wl_display_flush(wl_display) < 0 && - errno != EAGAIN) { - wl_display_cancel_read(wl_display); - return -errno; - } - - fds[0] = (struct pollfd) { wl_display_get_fd(wl_display), POLLIN }; - - ret = poll(fds, ARRAY_LENGTH(fds), timeout); - if (ret > 0) { - if (fds[0].revents & POLLIN) { - wl_display_read_events(wl_display); - dispatch_count += wl_display_dispatch_pending(wl_display); - return dispatch_count; - } else { - wl_display_cancel_read(wl_display); - return dispatch_count; - } - } else if (ret == 0) { - wl_display_cancel_read(wl_display); - return dispatch_count; - } else { - wl_display_cancel_read(wl_display); - return -errno; - } -} - static void libdecor_plugin_gtk_set_handle_application_cursor(bool handle_cursor){ ctx.handle_cursor = handle_cursor; @@ -1765,7 +1777,7 @@ redraw_scale(struct border_component *cmpnt){ int scale = 1; bool need_commit = false; - if (cmpnt->wl_surface != NULL){ + if (cmpnt->wl_surface != 0){ wl_list_for_each(surface_output, &cmpnt->output_list, link){ scale = MAX(scale, surface_output->output->scale); } @@ -2571,7 +2583,7 @@ static bool update_local_cursor(struct seat *seat){ bool result = false; - if (!seat->pointer_focus){ + if (seat->pointer_focus == 0){ seat->current_cursor = seat->cursor_left_ptr; } else{ @@ -2639,26 +2651,21 @@ update_local_cursor(struct seat *seat){ } static void -send_cursor(struct seat *seat) -{ - struct wl_cursor_image *image; - struct wl_buffer *buffer; - - if (seat->pointer_focus == NULL || seat->current_cursor == NULL) - return; - - image = seat->current_cursor->images[0]; - buffer = wl_cursor_image_get_buffer(image); - wl_surface_attach(seat->cursor_surface, buffer, 0, 0); - wl_surface_set_buffer_scale(seat->cursor_surface, seat->cursor_scale); - wl_surface_damage_buffer(seat->cursor_surface, 0, 0, - image->width * seat->cursor_scale, - image->height * seat->cursor_scale); - wl_surface_commit(seat->cursor_surface); - wl_pointer_set_cursor(seat->wl_pointer, seat->serial, - seat->cursor_surface, - image->hotspot_x / seat->cursor_scale, - image->hotspot_y / seat->cursor_scale); +send_cursor(struct seat *seat){ + if (seat->pointer_focus != 0 && seat->current_cursor != 0){ + struct wl_cursor_image *image = seat->current_cursor->images[0]; + struct wl_buffer *buffer = wl_cursor_image_get_buffer(image); + wl_surface_attach(seat->cursor_surface, buffer, 0, 0); + wl_surface_set_buffer_scale(seat->cursor_surface, seat->cursor_scale); + wl_surface_damage_buffer(seat->cursor_surface, 0, 0, + image->width * seat->cursor_scale, + image->height * seat->cursor_scale); + wl_surface_commit(seat->cursor_surface); + wl_pointer_set_cursor(seat->wl_pointer, seat->serial, + seat->cursor_surface, + image->hotspot_x / seat->cursor_scale, + image->hotspot_y / seat->cursor_scale); + } } static void @@ -2692,7 +2699,7 @@ static void pointer_leave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface){ struct seat *seat = data; - seat->pointer_focus = NULL; + seat->pointer_focus = 0; if (surface != 0 && own_proxy(surface)){ ctx.titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT; @@ -2713,52 +2720,51 @@ pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, struct seat *seat = data; struct header_element_data new_focus; - if (!seat->pointer_focus || !own_proxy(seat->pointer_focus)) - return; - - seat->pointer_x = wl_fixed_to_int(surface_x); - seat->pointer_y = wl_fixed_to_int(surface_y); - if (update_local_cursor(seat)){ - send_cursor(seat); - } - - /* avoid warnings after decoration has been turned off */ - if (!GTK_IS_WIDGET(ctx.header) || ctx.active->type != HEADER){ - ctx.hdr_focus.type = HEADER_NONE; - } - - new_focus = get_header_focus(GTK_HEADER_BAR(ctx.header), - seat->pointer_x, seat->pointer_y); - - /* only update if widget change so that we keep the state */ - if (ctx.hdr_focus.widget != new_focus.widget) { - ctx.hdr_focus = new_focus; - } - ctx.hdr_focus.state |= GTK_STATE_FLAG_PRELIGHT; - /* redraw with updated button visuals */ - draw_title_bar(); - wl_surface_commit(ctx.wl_surface); - - switch (ctx.titlebar_gesture.state) { - case TITLEBAR_GESTURE_STATE_BUTTON_PRESSED: - if (ctx.titlebar_gesture.first_pressed_button == BTN_LEFT) { - if (ABS((double)seat->pointer_x - (double)ctx.titlebar_gesture.pressed_x) > ctx.drag_threshold || - ABS((double)seat->pointer_y - (double)ctx.titlebar_gesture.pressed_y) > ctx.drag_threshold){ - libdecor_frame_move(seat->wl_seat, ctx.titlebar_gesture.pressed_serial); - } + if (seat->pointer_focus != 0 && own_proxy(seat->pointer_focus)){ + seat->pointer_x = wl_fixed_to_int(surface_x); + seat->pointer_y = wl_fixed_to_int(surface_y); + if (update_local_cursor(seat)){ + send_cursor(seat); + } + + /* avoid warnings after decoration has been turned off */ + if (!GTK_IS_WIDGET(ctx.header) || ctx.active->type != HEADER){ + ctx.hdr_focus.type = HEADER_NONE; + } + + new_focus = get_header_focus(GTK_HEADER_BAR(ctx.header), + seat->pointer_x, seat->pointer_y); + + /* only update if widget change so that we keep the state */ + if (ctx.hdr_focus.widget != new_focus.widget) { + ctx.hdr_focus = new_focus; + } + ctx.hdr_focus.state |= GTK_STATE_FLAG_PRELIGHT; + /* redraw with updated button visuals */ + draw_title_bar(); + wl_surface_commit(ctx.wl_surface); + + switch (ctx.titlebar_gesture.state) { + case TITLEBAR_GESTURE_STATE_BUTTON_PRESSED: + if (ctx.titlebar_gesture.first_pressed_button == BTN_LEFT) { + if (ABS((double)seat->pointer_x - (double)ctx.titlebar_gesture.pressed_x) > ctx.drag_threshold || + ABS((double)seat->pointer_y - (double)ctx.titlebar_gesture.pressed_y) > ctx.drag_threshold){ + libdecor_frame_move(seat->wl_seat, ctx.titlebar_gesture.pressed_serial); + } + } + case TITLEBAR_GESTURE_STATE_INIT: + case TITLEBAR_GESTURE_STATE_CONSUMED: + case TITLEBAR_GESTURE_STATE_DISCARDED: + break; } - case TITLEBAR_GESTURE_STATE_INIT: - case TITLEBAR_GESTURE_STATE_CONSUMED: - case TITLEBAR_GESTURE_STATE_DISCARDED: - break; } } static void handle_button_on_shadow(struct seat *seat, uint32_t serial, uint32_t time, uint32_t button, uint32_t state){ - enum libdecor_resize_edge edge = LIBDECOR_RESIZE_EDGE_NONE; - edge = component_edge(ctx.active, seat->pointer_x, seat->pointer_y, SHADOW_MARGIN); + enum libdecor_resize_edge edge = + component_edge(ctx.active, seat->pointer_x, seat->pointer_y, SHADOW_MARGIN); if (edge != LIBDECOR_RESIZE_EDGE_NONE && (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ libdecor_frame_resize(seat->wl_seat, serial, edge); @@ -3072,46 +3078,6 @@ const struct wl_touch_listener touch_listener = { touch_cancel }; -static void -output_geometry(void *data, struct wl_output *wl_output, - int32_t x, int32_t y, - int32_t physical_width, int32_t physical_height, - int32_t subpixel, const char *make, const char *model, - int32_t transform){} - -static void -output_mode(void *data, struct wl_output *wl_output, - uint32_t flags, int32_t width, int32_t height, - int32_t refresh){} - -static void -output_done(void *data, struct wl_output *wl_output){ - struct output *output = data; - struct seat *seat; - - if (ctx.decoration_type != DECORATION_TYPE_NONE){ - redraw_scale(&ctx.shadow); - } - wl_list_for_each(seat, &ctx.seat_list, link) { - if (update_local_cursor(seat)){ - send_cursor(seat); - } - } -} - -static void -output_scale(void *data, struct wl_output *wl_output, int32_t factor){ - struct output *output = data; - output->scale = factor; -} - -const struct wl_output_listener output_listener = { - output_geometry, - output_mode, - output_done, - output_scale -}; - static void remove_surface_outputs(struct border_component *cmpnt, const struct output *output){ struct surface_output *surface_output; diff --git a/digesting_libdecor.h b/digesting_libdecor.h index ad1fd87..813fc25 100644 --- a/digesting_libdecor.h +++ b/digesting_libdecor.h @@ -287,8 +287,6 @@ enum titlebar_gesture { void libdecor_frame_set_visibility(bool visible); void libdecor_frame_show_window_menu(struct wl_seat *wl_seat, uint32_t serial, int x, int y); -void libdecor_frame_popup_grab(const char *seat_name); -void libdecor_frame_popup_ungrab(const char *seat_name); void libdecor_frame_translate_coordinate(int surface_x, int surface_y, int *frame_x, int *frame_y); void libdecor_frame_resize(struct wl_seat *wl_seat, uint32_t serial, enum libdecor_resize_edge edge); @@ -301,8 +299,6 @@ void libdecor_frame_map(void); bool libdecor_configuration_get_content_size(struct libdecor_configuration *configuration, int *width, int *height); -int libdecor_dispatch(int timeout); - // #include "libdecor-cairo-blur.h" int blur_surface(cairo_surface_t *surface, int margin); @@ -331,19 +327,20 @@ static void init_wl_output( uint32_t id, uint32_t version); static void output_removed(struct output *output); -static void draw_header_button(cairo_t *cr, cairo_surface_t *surface, enum header_element button_type); - static const char *libdecor_gtk_proxy_tag = "libdecor-gtk"; -static int libdecor_plugin_gtk_dispatch(int timeout); static void libdecor_plugin_gtk_set_handle_application_cursor(bool handle_cursor); static void libdecor_plugin_gtk_frame_free(void); static void libdecor_plugin_gtk_frame_commit(struct libdecor_state *state, struct libdecor_configuration *configuration); -static void libdecor_plugin_gtk_frame_popup_grab(const char *seat_name); -static void libdecor_plugin_gtk_frame_popup_ungrab(const char *seat_name); static void libdecor_plugin_gtk_frame_get_border_size(enum libdecor_window_state window_state, int *left, int *right, int *top, int *bottom); +static bool update_local_cursor(struct seat *seat); static void draw_decoration(void); +static void draw_header_button(cairo_t *cr, cairo_surface_t *surface, enum header_element button_type); +static void redraw_scale(struct border_component *cmpnt); +static void send_cursor(struct seat *seat); +static void buffer_free(struct buffer *buffer); +static void draw_border_component(struct border_component *border_component); // digesting_libdecor