[mutter/wayland] cursor-tracker: Use a sync methodology for the cursor image
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wayland] cursor-tracker: Use a sync methodology for the cursor image
- Date: Tue, 19 Nov 2013 00:34:47 +0000 (UTC)
commit d96b053c9d5eb602407578481bbd3b9f1af47499
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Mon Nov 18 19:19:42 2013 -0500
cursor-tracker: Use a sync methodology for the cursor image
Rather than have MetaWaylandSeat do all the state management itself,
put the split between the root cursor and the window cursor in the
cursor tracker itself. We'll expand this to add a "grab" cursor in
the next commit, allowing us to force a cursor on grab operations.
src/core/meta-cursor-tracker-private.h | 16 +-
src/core/meta-cursor-tracker.c | 257 +++++++++++++++++++-------------
src/wayland/meta-wayland-seat.c | 26 +---
3 files changed, 164 insertions(+), 135 deletions(-)
---
diff --git a/src/core/meta-cursor-tracker-private.h b/src/core/meta-cursor-tracker-private.h
index e18d315..ffa08df 100644
--- a/src/core/meta-cursor-tracker-private.h
+++ b/src/core/meta-cursor-tracker-private.h
@@ -31,18 +31,16 @@
gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
XEvent *xevent);
-void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
- MetaCursor cursor);
-void meta_cursor_tracker_revert_root (MetaCursorTracker *tracker);
-void meta_cursor_tracker_set_buffer (MetaCursorTracker *tracker,
- struct wl_resource *buffer,
- int hot_x,
- int hot_y);
+void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
+ struct wl_resource *buffer,
+ int hot_x,
+ int hot_y);
+void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker);
+void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
+ MetaCursor cursor);
void meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
int new_x,
int new_y);
void meta_cursor_tracker_paint (MetaCursorTracker *tracker);
-void meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker,
- ClutterActor *stage);
#endif
diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c
index cff5f3e..e4cf92f 100644
--- a/src/core/meta-cursor-tracker.c
+++ b/src/core/meta-cursor-tracker.c
@@ -68,11 +68,31 @@ struct _MetaCursorTracker {
MetaScreen *screen;
gboolean is_showing;
- gboolean has_cursor;
gboolean has_hw_cursor;
- MetaCursorReference *sprite;
+ /* The cursor tracker stores the cursor for the window with
+ * pointer focus, and the cursor for the root window, which
+ * contains either the default arrow cursor or the 'busy'
+ * hourglass if we're launching an app.
+ *
+ * We choose the first one available -- if there's a window
+ * cursor, we choose that, otherwise we choose the root
+ * cursor.
+ *
+ * The displayed_cursor contains the chosen cursor.
+ */
+ MetaCursorReference *displayed_cursor;
+
+ /* Wayland clients can set a NULL buffer as their cursor
+ * explicitly, which means that we shouldn't display anything.
+ * So, we can't simply store a NULL in window_cursor to
+ * determine an unset window cursor; we need an extra boolean.
+ */
+ gboolean has_window_cursor;
+ MetaCursorReference *window_cursor;
+
MetaCursorReference *root_cursor;
+
MetaCursorReference *default_cursors[META_CURSOR_LAST];
int current_x, current_y;
@@ -98,9 +118,6 @@ enum {
static guint signals[LAST_SIGNAL];
-static void meta_cursor_tracker_set_sprite (MetaCursorTracker *tracker,
- MetaCursorReference *sprite);
-
static void meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker,
MetaCRTC *crtc,
gboolean has_hw_cursor);
@@ -354,7 +371,7 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
self->ref_count = 1;
self->hot_x = hot_x;
self->hot_y = hot_y;
-
+
backend = clutter_get_default_backend ();
cogl_context = clutter_backend_get_cogl_context (backend);
@@ -520,8 +537,8 @@ meta_cursor_tracker_finalize (GObject *object)
MetaCursorTracker *self = META_CURSOR_TRACKER (object);
int i;
- if (self->sprite)
- meta_cursor_reference_unref (self->sprite);
+ if (self->displayed_cursor)
+ meta_cursor_reference_unref (self->displayed_cursor);
if (self->root_cursor)
meta_cursor_reference_unref (self->root_cursor);
@@ -646,6 +663,17 @@ meta_cursor_tracker_get_for_screen (MetaScreen *screen)
return self;
}
+static void
+set_window_cursor (MetaCursorTracker *tracker,
+ gboolean has_cursor,
+ MetaCursorReference *cursor)
+{
+ g_clear_pointer (&tracker->window_cursor, meta_cursor_reference_unref);
+ if (cursor)
+ tracker->window_cursor = meta_cursor_reference_ref (cursor);
+ tracker->has_window_cursor = has_cursor;
+}
+
gboolean
meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
XEvent *xevent)
@@ -662,7 +690,7 @@ meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
if (notify_event->subtype != XFixesDisplayCursorNotify)
return FALSE;
- g_clear_pointer (&tracker->sprite, meta_cursor_reference_unref);
+ set_window_cursor (tracker, FALSE, NULL);
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
return TRUE;
@@ -677,7 +705,7 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
gboolean free_cursor_data;
CoglContext *ctx;
- if (tracker->sprite)
+ if (tracker->has_window_cursor)
return;
cursor_image = XFixesGetCursorImage (tracker->screen->display->xdisplay);
@@ -725,9 +753,11 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
if (sprite != NULL)
{
- tracker->sprite = meta_cursor_reference_take_texture (sprite);
- tracker->sprite->hot_x = cursor_image->xhot;
- tracker->sprite->hot_y = cursor_image->yhot;
+ MetaCursorReference *cursor = meta_cursor_reference_take_texture (sprite);
+ cursor->hot_x = cursor_image->xhot;
+ cursor->hot_y = cursor_image->yhot;
+
+ set_window_cursor (tracker, TRUE, cursor);
}
XFree (cursor_image);
}
@@ -745,8 +775,8 @@ meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
if (!meta_is_wayland_compositor ())
ensure_xfixes_cursor (tracker);
- if (tracker->sprite)
- return COGL_TEXTURE (tracker->sprite->texture);
+ if (tracker->displayed_cursor)
+ return COGL_TEXTURE (tracker->displayed_cursor->texture);
else
return NULL;
}
@@ -768,12 +798,13 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
if (!meta_is_wayland_compositor ())
ensure_xfixes_cursor (tracker);
- if (tracker->sprite)
+ if (tracker->displayed_cursor)
{
+ MetaCursorReference *displayed_cursor = tracker->displayed_cursor;
if (x)
- *x = tracker->sprite->hot_x;
+ *x = displayed_cursor->hot_x;
if (y)
- *y = tracker->sprite->hot_y;
+ *y = displayed_cursor->hot_y;
}
else
{
@@ -799,6 +830,28 @@ ensure_wayland_cursor (MetaCursorTracker *tracker,
}
void
+meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
+ struct wl_resource *buffer,
+ int hot_x,
+ int hot_y)
+{
+ MetaCursorReference *cursor;
+
+ if (buffer)
+ cursor = meta_cursor_reference_from_buffer (tracker, buffer, hot_x, hot_y);
+ else
+ cursor = NULL;
+
+ set_window_cursor (tracker, TRUE, cursor);
+}
+
+void
+meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker)
+{
+ set_window_cursor (tracker, FALSE, NULL);
+}
+
+void
meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
MetaCursor cursor)
{
@@ -824,12 +877,6 @@ meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
}
}
-void
-meta_cursor_tracker_revert_root (MetaCursorTracker *tracker)
-{
- meta_cursor_tracker_set_sprite (tracker, tracker->root_cursor);
-}
-
static void
update_hw_cursor (MetaCursorTracker *tracker)
{
@@ -838,7 +885,7 @@ update_hw_cursor (MetaCursorTracker *tracker)
unsigned int i, n_crtcs;
gboolean enabled;
- enabled = tracker->has_cursor && tracker->sprite->bo != NULL;
+ enabled = tracker->displayed_cursor && tracker->displayed_cursor->bo != NULL;
tracker->has_hw_cursor = enabled;
monitors = meta_monitor_manager_get ();
@@ -884,67 +931,85 @@ move_hw_cursor (MetaCursorTracker *tracker)
}
}
-void
-meta_cursor_tracker_set_buffer (MetaCursorTracker *tracker,
- struct wl_resource *buffer,
- int hot_x,
- int hot_y)
+static MetaCursorReference *
+get_displayed_cursor (MetaCursorTracker *tracker)
{
- MetaCursorReference *new_cursor;
+ if (!tracker->is_showing)
+ return NULL;
- if (buffer)
- {
- new_cursor = meta_cursor_reference_from_buffer (tracker, buffer, hot_x, hot_y);
- meta_cursor_tracker_set_sprite (tracker, new_cursor);
- meta_cursor_reference_unref (new_cursor);
- }
- else
- meta_cursor_tracker_set_sprite (tracker, NULL);
+ if (tracker->has_window_cursor)
+ return tracker->window_cursor;
+
+ return tracker->root_cursor;
}
static void
-meta_cursor_tracker_set_sprite (MetaCursorTracker *tracker,
- MetaCursorReference *sprite)
+sync_displayed_cursor (MetaCursorTracker *tracker)
{
- g_assert (meta_is_wayland_compositor ());
+ MetaCursorReference *displayed_cursor = get_displayed_cursor (tracker);
- if (sprite == tracker->sprite)
+ if (tracker->displayed_cursor == displayed_cursor)
return;
- g_clear_pointer (&tracker->sprite, meta_cursor_reference_unref);
+ g_clear_pointer (&tracker->displayed_cursor, meta_cursor_reference_unref);
+ if (displayed_cursor)
+ tracker->displayed_cursor = meta_cursor_reference_ref (displayed_cursor);
- if (sprite)
- {
- tracker->sprite = meta_cursor_reference_ref (sprite);
- cogl_pipeline_set_layer_texture (tracker->pipeline, 0, COGL_TEXTURE (tracker->sprite->texture));
- }
+ if (displayed_cursor)
+ cogl_pipeline_set_layer_texture (tracker->pipeline, 0, COGL_TEXTURE (displayed_cursor->texture));
else
cogl_pipeline_set_layer_texture (tracker->pipeline, 0, NULL);
- tracker->has_cursor = tracker->sprite != NULL && tracker->is_showing;
update_hw_cursor (tracker);
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
-
- meta_cursor_tracker_update_position (tracker, tracker->current_x, tracker->current_y);
}
-void
-meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
- int new_x,
- int new_y)
+static void
+meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker)
{
+ MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
+ ClutterActor *stage = compositor->stage;
+ cairo_rectangle_int_t clip;
+
g_assert (meta_is_wayland_compositor ());
- tracker->current_x = new_x;
- tracker->current_y = new_y;
+ if (tracker->previous_is_valid)
+ {
+ cairo_rectangle_int_t clip = {
+ .x = tracker->previous_rect.x,
+ .y = tracker->previous_rect.y,
+ .width = tracker->previous_rect.width,
+ .height = tracker->previous_rect.height
+ };
+ clutter_actor_queue_redraw_with_clip (stage, &clip);
+ tracker->previous_is_valid = FALSE;
+ }
+
+ if (tracker->has_hw_cursor || !tracker->displayed_cursor)
+ return;
+
+ clip.x = tracker->current_rect.x;
+ clip.y = tracker->current_rect.y;
+ clip.width = tracker->current_rect.width;
+ clip.height = tracker->current_rect.height;
+ clutter_actor_queue_redraw_with_clip (stage, &clip);
+}
+
+static void
+sync_cursor (MetaCursorTracker *tracker)
+{
+ MetaCursorReference *displayed_cursor;
+
+ sync_displayed_cursor (tracker);
+ displayed_cursor = tracker->displayed_cursor;
- if (tracker->sprite)
+ if (displayed_cursor)
{
- tracker->current_rect.x = tracker->current_x - tracker->sprite->hot_x;
- tracker->current_rect.y = tracker->current_y - tracker->sprite->hot_y;
- tracker->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (tracker->sprite->texture));
- tracker->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (tracker->sprite->texture));
+ tracker->current_rect.x = tracker->current_x - displayed_cursor->hot_x;
+ tracker->current_rect.y = tracker->current_y - displayed_cursor->hot_y;
+ tracker->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (displayed_cursor->texture));
+ tracker->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (displayed_cursor->texture));
}
else
{
@@ -956,6 +1021,21 @@ meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
if (tracker->has_hw_cursor)
move_hw_cursor (tracker);
+ else
+ meta_cursor_tracker_queue_redraw (tracker);
+}
+
+void
+meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
+ int new_x,
+ int new_y)
+{
+ g_assert (meta_is_wayland_compositor ());
+
+ tracker->current_x = new_x;
+ tracker->current_y = new_y;
+
+ sync_cursor (tracker);
}
void
@@ -963,7 +1043,7 @@ meta_cursor_tracker_paint (MetaCursorTracker *tracker)
{
g_assert (meta_is_wayland_compositor ());
- if (tracker->has_hw_cursor || !tracker->has_cursor)
+ if (tracker->has_hw_cursor || !tracker->displayed_cursor)
return;
cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
@@ -979,36 +1059,6 @@ meta_cursor_tracker_paint (MetaCursorTracker *tracker)
tracker->previous_is_valid = TRUE;
}
-void
-meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker,
- ClutterActor *stage)
-{
- cairo_rectangle_int_t clip;
-
- g_assert (meta_is_wayland_compositor ());
-
- if (tracker->previous_is_valid)
- {
- cairo_rectangle_int_t clip = {
- .x = tracker->previous_rect.x,
- .y = tracker->previous_rect.y,
- .width = tracker->previous_rect.width,
- .height = tracker->previous_rect.height
- };
- clutter_actor_queue_redraw_with_clip (stage, &clip);
- tracker->previous_is_valid = FALSE;
- }
-
- if (tracker->has_hw_cursor || !tracker->has_cursor)
- return;
-
- clip.x = tracker->current_rect.x;
- clip.y = tracker->current_rect.y;
- clip.width = tracker->current_rect.width;
- clip.height = tracker->current_rect.height;
- clutter_actor_queue_redraw_with_clip (stage, &clip);
-}
-
static void
meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker,
MetaCRTC *crtc,
@@ -1016,15 +1066,16 @@ meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker,
{
if (has)
{
+ MetaCursorReference *displayed_cursor = tracker->displayed_cursor;
union gbm_bo_handle handle;
int width, height;
int hot_x, hot_y;
- handle = gbm_bo_get_handle (tracker->sprite->bo);
- width = gbm_bo_get_width (tracker->sprite->bo);
- height = gbm_bo_get_height (tracker->sprite->bo);
- hot_x = tracker->sprite->hot_x;
- hot_y = tracker->sprite->hot_y;
+ handle = gbm_bo_get_handle (displayed_cursor->bo);
+ width = gbm_bo_get_width (displayed_cursor->bo);
+ height = gbm_bo_get_height (displayed_cursor->bo);
+ hot_x = displayed_cursor->hot_x;
+ hot_y = displayed_cursor->hot_y;
drmModeSetCursor2 (tracker->drm_fd, crtc->crtc_id, handle.u32,
width, height, hot_x, hot_y);
@@ -1100,13 +1151,7 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
if (meta_is_wayland_compositor ())
{
- MetaWaylandCompositor *compositor;
-
- compositor = meta_wayland_compositor_get_default ();
-
- tracker->has_cursor = tracker->sprite != NULL && visible;
- update_hw_cursor (tracker);
- meta_cursor_tracker_queue_redraw (tracker, compositor->stage);
+ sync_cursor (tracker);
}
else
{
diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c
index 0b9415a..377e7f2 100644
--- a/src/wayland/meta-wayland-seat.c
+++ b/src/wayland/meta-wayland-seat.c
@@ -51,14 +51,7 @@ static void
pointer_unmap_sprite (MetaWaylandSeat *seat)
{
if (seat->cursor_tracker)
- {
- meta_cursor_tracker_set_buffer (seat->cursor_tracker,
- NULL, 0, 0);
-
- if (seat->current_stage)
- meta_cursor_tracker_queue_redraw (seat->cursor_tracker,
- CLUTTER_ACTOR (seat->current_stage));
- }
+ meta_cursor_tracker_set_window_cursor (seat->cursor_tracker, NULL, 0, 0);
if (seat->sprite)
{
@@ -76,14 +69,10 @@ meta_wayland_seat_update_sprite (MetaWaylandSeat *seat)
return;
buffer = seat->sprite->buffer_ref.buffer->resource;
- meta_cursor_tracker_set_buffer (seat->cursor_tracker,
- buffer,
- seat->hotspot_x,
- seat->hotspot_y);
-
- if (seat->current_stage)
- meta_cursor_tracker_queue_redraw (seat->cursor_tracker,
- CLUTTER_ACTOR (seat->current_stage));
+ meta_cursor_tracker_set_window_cursor (seat->cursor_tracker,
+ buffer,
+ seat->hotspot_x,
+ seat->hotspot_y);
}
static void
@@ -377,10 +366,7 @@ meta_wayland_seat_update_pointer (MetaWaylandSeat *seat,
wl_fixed_to_int (seat->pointer.y));
if (seat->pointer.current == NULL)
- meta_cursor_tracker_revert_root (seat->cursor_tracker);
-
- meta_cursor_tracker_queue_redraw (seat->cursor_tracker,
- CLUTTER_ACTOR (event->any.stage));
+ meta_cursor_tracker_unset_window_cursor (seat->cursor_tracker);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]