summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Hua <william.hua@canonical.com>2016-07-04 15:31:16 -0400
committerWilliam Hua <william.hua@canonical.com>2016-07-18 10:36:49 -0400
commitf4778e48afc707a7b3407550150740950a8c8bf3 (patch)
tree5819b7adff2e709b257b8a0eca839dd1aab17319
parentd703885bad9537b26be81c2cf32419af5da3f71a (diff)
downloadgtk+-wip/attente/popup-at.tar.gz
mir: implement gdk_window_move_to_rect ()wip/attente/popup-at
https://bugzilla.gnome.org/show_bug.cgi?id=756579
-rw-r--r--gdk/mir/gdkmirwindowimpl.c130
1 files changed, 114 insertions, 16 deletions
diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
index 5ca9d89511..1a19ec9b61 100644
--- a/gdk/mir/gdkmirwindowimpl.c
+++ b/gdk/mir/gdkmirwindowimpl.c
@@ -46,6 +46,11 @@ struct _GdkMirWindowImpl
gint transient_x;
gint transient_y;
+ /* Anchor rectangle */
+ gboolean has_rect;
+ MirRectangle rect;
+ MirEdgeAttachment edge;
+
/* Desired surface attributes */
GdkWindowTypeHint type_hint;
MirSurfaceState surface_state;
@@ -171,6 +176,8 @@ create_mir_surface (GdkDisplay *display,
gint width,
gint height,
GdkWindowTypeHint type,
+ const MirRectangle *rect,
+ MirEdgeAttachment edge,
MirBufferUsage buffer_usage)
{
MirSurface *parent_surface = NULL;
@@ -178,7 +185,7 @@ create_mir_surface (GdkDisplay *display,
MirConnection *connection;
MirPixelFormat format;
MirSurface *surface;
- MirRectangle rect;
+ MirRectangle real_rect;
connection = gdk_mir_display_get_mir_connection (display);
format = _gdk_mir_display_get_pixel_format (display, buffer_usage);
@@ -202,6 +209,25 @@ create_mir_surface (GdkDisplay *display,
}
}
+ if (rect)
+ {
+ real_rect = *rect;
+
+ while (parent && !gdk_window_has_native (parent) && gdk_window_get_effective_parent (parent))
+ {
+ real_rect.left += parent->x;
+ real_rect.top += parent->y;
+ parent = gdk_window_get_effective_parent (parent);
+ }
+ }
+ else
+ {
+ real_rect.left = x;
+ real_rect.top = y;
+ real_rect.width = 1;
+ real_rect.height = 1;
+ }
+
switch (type)
{
case GDK_WINDOW_TYPE_HINT_DIALOG:
@@ -216,17 +242,13 @@ create_mir_surface (GdkDisplay *display,
case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
case GDK_WINDOW_TYPE_HINT_TOOLBAR:
case GDK_WINDOW_TYPE_HINT_COMBO:
- rect.left = x;
- rect.top = y;
- rect.width = 1;
- rect.height = 1;
spec = mir_connection_create_spec_for_menu (connection,
width,
height,
format,
parent_surface,
- &rect,
- mir_edge_attachment_any);
+ &real_rect,
+ edge);
break;
case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
case GDK_WINDOW_TYPE_HINT_UTILITY:
@@ -239,16 +261,12 @@ create_mir_surface (GdkDisplay *display,
case GDK_WINDOW_TYPE_HINT_DND:
case GDK_WINDOW_TYPE_HINT_TOOLTIP:
case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
- rect.left = x;
- rect.top = y;
- rect.width = 1;
- rect.height = 1;
spec = mir_connection_create_spec_for_tooltip (connection,
width,
height,
format,
parent_surface,
- &rect);
+ &real_rect);
break;
case GDK_WINDOW_TYPE_HINT_NORMAL:
case GDK_WINDOW_TYPE_HINT_DESKTOP:
@@ -328,10 +346,15 @@ ensure_surface_full (GdkWindow *window,
*/
window_ref = _gdk_mir_event_source_get_window_reference (window);
- impl->surface = create_mir_surface (gdk_window_get_display (window), impl->transient_for,
- impl->transient_x, impl->transient_y,
- window->width, window->height,
+ impl->surface = create_mir_surface (gdk_window_get_display (window),
+ impl->transient_for,
+ impl->transient_x,
+ impl->transient_y,
+ window->width,
+ window->height,
impl->type_hint,
+ impl->has_rect ? &impl->rect : NULL,
+ impl->has_rect ? impl->edge : mir_edge_attachment_any,
buffer_usage);
/* FIXME: can't make an initial resize event */
@@ -615,8 +638,9 @@ gdk_mir_window_impl_move_resize (GdkWindow *window,
/* Transient windows can move wherever they want */
if (with_move)
{
- if (x != impl->transient_x || y != impl->transient_y)
+ if (impl->has_rect || x != impl->transient_x || y != impl->transient_y)
{
+ impl->has_rect = FALSE;
impl->transient_x = x;
impl->transient_y = y;
recreate_surface = TRUE;
@@ -639,6 +663,79 @@ gdk_mir_window_impl_move_resize (GdkWindow *window,
}
}
+static MirEdgeAttachment
+get_edge_for_anchors (GdkGravity rect_anchor,
+ GdkGravity window_anchor,
+ GdkAnchorHints anchor_hints)
+{
+ MirEdgeAttachment edge = 0;
+
+ if (anchor_hints & GDK_ANCHOR_FLIP_X)
+ edge |= mir_edge_attachment_vertical;
+
+ if (anchor_hints & GDK_ANCHOR_FLIP_Y)
+ edge |= mir_edge_attachment_horizontal;
+
+ return edge;
+}
+
+static void
+get_rect_for_edge (MirRectangle *out_rect,
+ const GdkRectangle *in_rect,
+ MirEdgeAttachment edge,
+ GdkWindow *window)
+{
+ out_rect->left = in_rect->x;
+ out_rect->top = in_rect->y;
+ out_rect->width = in_rect->width;
+ out_rect->height = in_rect->height;
+
+ switch (edge)
+ {
+ case mir_edge_attachment_vertical:
+ out_rect->left += window->shadow_right;
+ out_rect->top -= window->shadow_top;
+ out_rect->width -= window->shadow_left + window->shadow_right;
+ out_rect->height += window->shadow_top + window->shadow_bottom;
+ break;
+
+ case mir_edge_attachment_horizontal:
+ out_rect->left -= window->shadow_left;
+ out_rect->top += window->shadow_bottom;
+ out_rect->width += window->shadow_left + window->shadow_right;
+ out_rect->height -= window->shadow_top + window->shadow_bottom;
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void
+gdk_mir_window_impl_move_to_rect (GdkWindow *window,
+ const GdkRectangle *rect,
+ GdkGravity rect_anchor,
+ GdkGravity window_anchor,
+ GdkAnchorHints anchor_hints,
+ gint rect_anchor_dx,
+ gint rect_anchor_dy)
+{
+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
+
+ impl->edge = get_edge_for_anchors (rect_anchor, window_anchor, anchor_hints);
+ get_rect_for_edge (&impl->rect, rect, impl->edge, window);
+ impl->has_rect = TRUE;
+
+ ensure_no_surface (window);
+
+ g_signal_emit_by_name (window,
+ "moved-to-rect",
+ NULL,
+ NULL,
+ FALSE,
+ FALSE);
+}
+
static void
gdk_mir_window_impl_set_background (GdkWindow *window,
cairo_pattern_t *pattern)
@@ -1524,6 +1621,7 @@ gdk_mir_window_impl_class_init (GdkMirWindowImplClass *klass)
impl_class->restack_under = gdk_mir_window_impl_restack_under;
impl_class->restack_toplevel = gdk_mir_window_impl_restack_toplevel;
impl_class->move_resize = gdk_mir_window_impl_move_resize;
+ impl_class->move_to_rect = gdk_mir_window_impl_move_to_rect;
impl_class->set_background = gdk_mir_window_impl_set_background;
impl_class->get_events = gdk_mir_window_impl_get_events;
impl_class->set_events = gdk_mir_window_impl_set_events;