[PATCH weston 2/2] shell: override the default pointer grab interface

Giulio Camuffo giuliocamuffo at gmail.com
Mon Sep 30 03:40:29 PDT 2013


when a fullscreen surface hides the cursor, such as mpv, we must
make sure that the cursor gets hidden also when it is over the
underlying black surface. so check if the surface under the pointer
is a black surface and focus on its parent surface.
this results in sending pointer coordinates that are outside of
the surface geometry.
---
 src/shell.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/src/shell.c b/src/shell.c
index f033e8c..bb05048 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -4557,6 +4557,88 @@ shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell)
 					  debug_binding, shell);
 }
 
+static void
+default_grab_focus(struct weston_pointer_grab *grab)
+{
+	struct weston_pointer *pointer = grab->pointer;
+	struct weston_surface *surface;
+	wl_fixed_t sx, sy;
+
+	if (pointer->button_count > 0)
+		return;
+
+	surface = weston_compositor_pick_surface(pointer->seat->compositor,
+						 pointer->x, pointer->y,
+						 &sx, &sy);
+
+	if (surface && surface->configure == &black_surface_configure) {
+		surface = surface->configure_private;
+	}
+	if (pointer->focus != surface) {
+		weston_pointer_set_focus(pointer, surface, sx, sy);
+	}
+}
+
+static void
+default_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
+{
+	struct weston_pointer *pointer = grab->pointer;
+	wl_fixed_t sx, sy;
+	struct wl_list *resource_list;
+	struct wl_resource *resource;
+
+	resource_list = &pointer->focus_resource_list;
+	wl_resource_for_each(resource, resource_list) {
+		weston_surface_from_global_fixed(pointer->focus,
+						 pointer->x, pointer->y,
+						 &sx, &sy);
+		wl_pointer_send_motion(resource, time, sx, sy);
+	}
+}
+
+static void
+default_grab_button(struct weston_pointer_grab *grab,
+		    uint32_t time, uint32_t button, uint32_t state_w)
+{
+	struct weston_pointer *pointer = grab->pointer;
+	struct weston_compositor *compositor = pointer->seat->compositor;
+	struct weston_surface *surface;
+	struct wl_resource *resource;
+	uint32_t serial;
+	enum wl_pointer_button_state state = state_w;
+	struct wl_display *display = compositor->wl_display;
+	wl_fixed_t sx, sy;
+	struct wl_list *resource_list;
+
+	resource_list = &pointer->focus_resource_list;
+	if (!wl_list_empty(resource_list)) {
+		serial = wl_display_next_serial(display);
+		wl_resource_for_each(resource, resource_list)
+			wl_pointer_send_button(resource,
+					       serial,
+					       time,
+					       button,
+					       state_w);
+	}
+
+	if (pointer->button_count == 0 &&
+	    state == WL_POINTER_BUTTON_STATE_RELEASED) {
+		surface = weston_compositor_pick_surface(compositor,
+							 pointer->x,
+							 pointer->y,
+							 &sx, &sy);
+
+		weston_pointer_set_focus(pointer, surface, sx, sy);
+	}
+}
+
+static const struct weston_pointer_grab_interface
+				default_pointer_grab_interface = {
+	default_grab_focus,
+	default_grab_motion,
+	default_grab_button
+};
+
 WL_EXPORT int
 module_init(struct weston_compositor *ec,
 	    int *argc, char *argv[])
@@ -4596,6 +4678,7 @@ module_init(struct weston_compositor *ec,
 	ec->shell_interface.resize = surface_resize;
 	ec->shell_interface.set_title = set_title;
 
+	weston_compositor_set_default_pointer_grab(ec, &default_pointer_grab_interface);
 	wl_list_init(&shell->input_panel.surfaces);
 
 	weston_layer_init(&shell->fullscreen_layer, &ec->cursor_layer.link);
-- 
1.8.4



More information about the wayland-devel mailing list