[gtk+] mir: handle surface placement events
- From: William Hua <williamhua src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] mir: handle surface placement events
- Date: Mon, 30 Jan 2017 08:08:47 +0000 (UTC)
commit 2088cc3395069a5ffa1ab0e7aee000113159919e
Author: William Hua <william hua canonical com>
Date: Sun Jan 29 11:24:43 2017 -0500
mir: handle surface placement events
This allows the Mir backend to properly emit "moved-to-rect."
gdk/mir/gdkmir-private.h | 2 +
gdk/mir/gdkmir.h | 1 +
gdk/mir/gdkmireventsource.c | 10 ++
gdk/mir/gdkmirwindowimpl.c | 207 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 220 insertions(+), 0 deletions(-)
---
diff --git a/gdk/mir/gdkmir-private.h b/gdk/mir/gdkmir-private.h
index 997cf47..d9fdeb4 100644
--- a/gdk/mir/gdkmir-private.h
+++ b/gdk/mir/gdkmir-private.h
@@ -91,6 +91,8 @@ void _gdk_mir_window_impl_set_surface_type (GdkMirWindowImpl *impl, MirSurfaceTy
void _gdk_mir_window_set_surface_output (GdkWindow *window, gdouble scale);
+void _gdk_mir_window_set_final_rect (GdkWindow *window, MirRectangle rect);
+
void _gdk_mir_window_impl_set_cursor_state (GdkMirWindowImpl *impl, gdouble x, gdouble y, gboolean
cursor_inside, guint button_state);
void _gdk_mir_window_impl_get_cursor_state (GdkMirWindowImpl *impl, gdouble *x, gdouble *y, gboolean
*cursor_inside, guint *button_state);
diff --git a/gdk/mir/gdkmir.h b/gdk/mir/gdkmir.h
index 38cc80c..6e92fcf 100644
--- a/gdk/mir/gdkmir.h
+++ b/gdk/mir/gdkmir.h
@@ -20,6 +20,7 @@
#include <gdk/gdk.h>
#include <mir_toolkit/mir_client_library.h>
+#include <mir_toolkit/events/surface_placement.h>
G_BEGIN_DECLS
diff --git a/gdk/mir/gdkmireventsource.c b/gdk/mir/gdkmireventsource.c
index d3c85b9..3ebf156 100644
--- a/gdk/mir/gdkmireventsource.c
+++ b/gdk/mir/gdkmireventsource.c
@@ -541,6 +541,13 @@ handle_surface_output_event (GdkWindow *window,
_gdk_mir_window_set_surface_output (window, mir_surface_output_event_get_scale (event));
}
+static void
+handle_surface_placement_event (GdkWindow *window,
+ const MirSurfacePlacementEvent *event)
+{
+ _gdk_mir_window_set_final_rect (window, mir_surface_placement_get_relative_position (event));
+}
+
typedef struct
{
GdkWindow *window;
@@ -600,6 +607,9 @@ gdk_mir_event_source_queue_event (GdkDisplay *display,
case mir_event_type_surface_output:
handle_surface_output_event (window, mir_event_get_surface_output_event (event));
break;
+ case mir_event_type_surface_placement:
+ handle_surface_placement_event (window, mir_event_get_surface_placement_event (event));
+ break;
default:
g_warning ("Ignoring unknown Mir event %d", mir_event_get_type (event));
// FIXME?
diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
index 25242f6..497069e 100644
--- a/gdk/mir/gdkmirwindowimpl.c
+++ b/gdk/mir/gdkmirwindowimpl.c
@@ -983,6 +983,213 @@ gdk_mir_window_impl_move_to_rect (GdkWindow *window,
update_surface_spec (window);
}
+static gint
+get_mir_placement_gravity_x (MirPlacementGravity gravity)
+{
+ switch (gravity)
+ {
+ case mir_placement_gravity_west:
+ case mir_placement_gravity_northwest:
+ case mir_placement_gravity_southwest:
+ return 0;
+
+ case mir_placement_gravity_center:
+ case mir_placement_gravity_north:
+ case mir_placement_gravity_south:
+ return 1;
+
+ case mir_placement_gravity_east:
+ case mir_placement_gravity_northeast:
+ case mir_placement_gravity_southeast:
+ return 2;
+ }
+
+ g_warn_if_reached ();
+
+ return 1;
+}
+
+static gint
+get_mir_placement_gravity_y (MirPlacementGravity gravity)
+{
+ switch (gravity)
+ {
+ case mir_placement_gravity_north:
+ case mir_placement_gravity_northwest:
+ case mir_placement_gravity_northeast:
+ return 0;
+
+ case mir_placement_gravity_center:
+ case mir_placement_gravity_west:
+ case mir_placement_gravity_east:
+ return 1;
+
+ case mir_placement_gravity_south:
+ case mir_placement_gravity_southwest:
+ case mir_placement_gravity_southeast:
+ return 2;
+ }
+
+ g_warn_if_reached ();
+
+ return 1;
+}
+
+static GdkRectangle
+get_unflipped_rect (const GdkRectangle *rect,
+ gint width,
+ gint height,
+ MirPlacementGravity rect_anchor,
+ MirPlacementGravity window_anchor,
+ gint rect_anchor_dx,
+ gint rect_anchor_dy)
+{
+ GdkRectangle unflipped_rect;
+
+ unflipped_rect.x = rect->x;
+ unflipped_rect.x += rect->width * get_mir_placement_gravity_x (rect_anchor) / 2;
+ unflipped_rect.x -= width * get_mir_placement_gravity_x (window_anchor) / 2;
+ unflipped_rect.x += rect_anchor_dx;
+ unflipped_rect.y = rect->y;
+ unflipped_rect.y += rect->height * get_mir_placement_gravity_y (rect_anchor) / 2;
+ unflipped_rect.y -= height * get_mir_placement_gravity_y (window_anchor) / 2;
+ unflipped_rect.y += rect_anchor_dy;
+ unflipped_rect.width = width;
+ unflipped_rect.height = height;
+
+ return unflipped_rect;
+}
+
+static MirPlacementGravity
+get_opposite_mir_placement_gravity (MirPlacementGravity gravity)
+{
+ switch (gravity)
+ {
+ case mir_placement_gravity_center:
+ return mir_placement_gravity_center;
+ case mir_placement_gravity_west:
+ return mir_placement_gravity_east;
+ case mir_placement_gravity_east:
+ return mir_placement_gravity_west;
+ case mir_placement_gravity_north:
+ return mir_placement_gravity_south;
+ case mir_placement_gravity_south:
+ return mir_placement_gravity_north;
+ case mir_placement_gravity_northwest:
+ return mir_placement_gravity_southeast;
+ case mir_placement_gravity_northeast:
+ return mir_placement_gravity_southwest;
+ case mir_placement_gravity_southwest:
+ return mir_placement_gravity_northeast;
+ case mir_placement_gravity_southeast:
+ return mir_placement_gravity_northwest;
+ }
+
+ g_warn_if_reached ();
+
+ return gravity;
+}
+
+static gint
+get_anchor_x (const GdkRectangle *rect,
+ MirPlacementGravity anchor)
+{
+ return rect->x + rect->width * get_mir_placement_gravity_x (anchor) / 2;
+}
+
+static gint
+get_anchor_y (const GdkRectangle *rect,
+ MirPlacementGravity anchor)
+{
+ return rect->y + rect->height * get_mir_placement_gravity_y (anchor) / 2;
+}
+
+void
+_gdk_mir_window_set_final_rect (GdkWindow *window,
+ MirRectangle rect)
+{
+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
+ GdkRectangle best_rect;
+ GdkRectangle worst_rect;
+ GdkRectangle flipped_rect;
+ GdkRectangle final_rect;
+ gboolean flipped_x = FALSE;
+ gboolean flipped_y = FALSE;
+ gint test_position;
+ gint final_position;
+ gint unflipped_offset;
+ gint flipped_offset;
+
+ g_return_if_fail (impl->has_rect);
+
+ best_rect = get_unflipped_rect (&impl->rect,
+ window->width,
+ window->height,
+ impl->rect_anchor,
+ impl->window_anchor,
+ impl->rect_anchor_dx,
+ impl->rect_anchor_dy);
+
+ worst_rect = get_unflipped_rect (&impl->rect,
+ window->width,
+ window->height,
+ get_opposite_mir_placement_gravity (impl->rect_anchor),
+ get_opposite_mir_placement_gravity (impl->window_anchor),
+ -impl->rect_anchor_dx,
+ -impl->rect_anchor_dy);
+
+ flipped_rect.x = best_rect.x;
+ flipped_rect.y = best_rect.y;
+ flipped_rect.width = window->width;
+ flipped_rect.height = window->height;
+
+ final_rect.x = rect.left - (impl->mir_rect.left - impl->rect.x);
+ final_rect.y = rect.top - (impl->mir_rect.top - impl->rect.y);
+ final_rect.width = rect.width;
+ final_rect.height = rect.height;
+
+ if (impl->anchor_hints & mir_placement_hints_flip_x)
+ {
+ test_position = get_anchor_x (&best_rect, impl->window_anchor);
+ final_position = get_anchor_x (&final_rect, impl->window_anchor);
+ unflipped_offset = final_position - test_position;
+
+ test_position = get_anchor_x (&worst_rect, get_opposite_mir_placement_gravity (impl->window_anchor));
+ final_position = get_anchor_x (&final_rect, get_opposite_mir_placement_gravity (impl->window_anchor));
+ flipped_offset = final_position - test_position;
+
+ if (ABS (flipped_offset) < ABS (unflipped_offset))
+ {
+ flipped_rect.x = worst_rect.x;
+ flipped_x = TRUE;
+ }
+ }
+
+ if (impl->anchor_hints & mir_placement_hints_flip_y)
+ {
+ test_position = get_anchor_y (&best_rect, impl->window_anchor);
+ final_position = get_anchor_y (&final_rect, impl->window_anchor);
+ unflipped_offset = final_position - test_position;
+
+ test_position = get_anchor_y (&worst_rect, get_opposite_mir_placement_gravity (impl->window_anchor));
+ final_position = get_anchor_y (&final_rect, get_opposite_mir_placement_gravity (impl->window_anchor));
+ flipped_offset = final_position - test_position;
+
+ if (ABS (flipped_offset) < ABS (unflipped_offset))
+ {
+ flipped_rect.y = worst_rect.y;
+ flipped_y = TRUE;
+ }
+ }
+
+ g_signal_emit_by_name (window,
+ "moved-to-rect",
+ &flipped_rect,
+ &final_rect,
+ flipped_x,
+ flipped_y);
+}
+
static GdkEventMask
gdk_mir_window_impl_get_events (GdkWindow *window)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]