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

Giulio Camuffo giuliocamuffo at gmail.com
Thu Nov 14 14:42:54 PST 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 instead.
this results in sending pointer coordinates that are outside of
the surface geometry.
---
 src/shell.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/src/shell.c b/src/shell.c
index fe332e1..fd6f57d 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -4892,6 +4892,96 @@ 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_view *view;
+	wl_fixed_t sx, sy;
+
+	if (pointer->button_count > 0)
+		return;
+
+	view = weston_compositor_pick_view(pointer->seat->compositor,
+					   pointer->x, pointer->y,
+					   &sx, &sy);
+
+	if (view && view->surface->configure == &black_surface_configure) {
+		view = view->surface->configure_private;
+	}
+	if (pointer->focus != view)
+		weston_pointer_set_focus(pointer, view, sx, sy);
+}
+
+static void
+default_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
+			    wl_fixed_t x, wl_fixed_t y)
+{
+	struct weston_pointer *pointer = grab->pointer;
+	wl_fixed_t sx, sy;
+	struct wl_list *resource_list;
+	struct wl_resource *resource;
+
+	weston_pointer_move(pointer, x, y);
+
+	resource_list = &pointer->focus_resource_list;
+	wl_resource_for_each(resource, resource_list) {
+		weston_view_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_view *view;
+	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) {
+		view = weston_compositor_pick_view(compositor,
+						   pointer->x, pointer->y,
+				     &sx, &sy);
+
+		weston_pointer_set_focus(pointer, view, sx, sy);
+		}
+}
+
+static void
+default_grab_cancel(struct weston_pointer_grab *grab)
+{
+}
+
+
+static const struct weston_pointer_grab_interface
+				default_pointer_grab_interface = {
+	default_grab_focus,
+	default_grab_motion,
+	default_grab_button,
+	default_grab_cancel
+};
+
 WL_EXPORT int
 module_init(struct weston_compositor *ec,
 	    int *argc, char *argv[])
@@ -4932,6 +5022,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.2



More information about the wayland-devel mailing list