Merge lp:~attente/gtk/gtk-mir into lp:~ubuntu-desktop/gtk/ubuntugtk3

Proposed by William Hua
Status: Merged
Merged at revision: 544
Proposed branch: lp:~attente/gtk/gtk-mir
Merge into: lp:~ubuntu-desktop/gtk/ubuntugtk3
Diff against target: 2085 lines (+1996/-2)
14 files modified
debian/changelog (+20/-0)
debian/control (+2/-1)
debian/control.in (+2/-1)
debian/patches/0001-mir-implement-window-properties.patch (+244/-0)
debian/patches/0002-mir-track-focused-window.patch (+91/-0)
debian/patches/0003-mir-connect-to-content-hub.patch (+108/-0)
debian/patches/0004-mir-copy-clipboard-data-to-content-hub.patch (+292/-0)
debian/patches/0005-mir-paste-clipboard-data-from-content-hub.patch (+415/-0)
debian/patches/0006-mir-properly-handle-empty-clipboard.patch (+37/-0)
debian/patches/0031-mir-fix-compile-time-warnings.patch (+77/-0)
debian/patches/0032-mir-use-modal-window-hint.patch (+76/-0)
debian/patches/0036-mir-use-mir_surface_spec_set_placement-for-menus.patch (+334/-0)
debian/patches/0037-mir-handle-surface-placement-events.patch (+287/-0)
debian/patches/series (+11/-0)
To merge this branch: bzr merge lp:~attente/gtk/gtk-mir
Reviewer Review Type Date Requested Status
Jeremy Bícha Approve
Review via email: mp+316716@code.launchpad.net

Commit message

  * debian/control:
  * debian/control.in:
    - Build depend on libcontent-hub-glib-dev
  * debian/patches/series:
  * debian/patches/0001-mir-implement-window-properties.patch:
  * debian/patches/0002-mir-track-focused-window.patch:
  * debian/patches/0003-mir-connect-to-content-hub.patch:
  * debian/patches/0004-mir-copy-clipboard-data-to-content-hub.patch:
  * debian/patches/0005-mir-paste-clipboard-data-from-content-hub.patch:
  * debian/patches/0006-mir-properly-handle-empty-clipboard.patch:
  * debian/patches/0031-mir-fix-compile-time-warnings.patch:
  * debian/patches/0032-mir-use-modal-window-hint.patch:
  * debian/patches/0036-mir-use-mir_surface_spec_set_placement-for-menus.patch:
  * debian/patches/0037-mir-handle-surface-placement-events.patch:
    - Add upstream patches from gtk-3-22 branch

Description of the change

Apply upstream patches from gtk-3-22 branch:

  * debian/control:
  * debian/control.in:
    - Build depend on libcontent-hub-glib-dev
  * debian/patches/series:
  * debian/patches/0001-mir-implement-window-properties.patch:
  * debian/patches/0002-mir-track-focused-window.patch:
  * debian/patches/0003-mir-connect-to-content-hub.patch:
  * debian/patches/0004-mir-copy-clipboard-data-to-content-hub.patch:
  * debian/patches/0005-mir-paste-clipboard-data-from-content-hub.patch:
  * debian/patches/0006-mir-properly-handle-empty-clipboard.patch:
  * debian/patches/0031-mir-fix-compile-time-warnings.patch:
  * debian/patches/0032-mir-use-modal-window-hint.patch:
  * debian/patches/0036-mir-use-mir_surface_spec_set_placement-for-menus.patch:
  * debian/patches/0037-mir-handle-surface-placement-events.patch:
    - Add upstream patches from gtk-3-22 branch

To post a comment you must log in.
Revision history for this message
Jeremy Bícha (jbicha) wrote :

Thanks!

review: Approve
lp:~attente/gtk/gtk-mir updated
544. By William Hua

* debian/control:
* debian/control.in:
  - Build depend on libcontent-hub-glib-dev
* debian/patches/series:
* debian/patches/0001-mir-implement-window-properties.patch:
* debian/patches/0002-mir-track-focused-window.patch:
* debian/patches/0003-mir-connect-to-content-hub.patch:
* debian/patches/0004-mir-copy-clipboard-data-to-content-hub.patch:
* debian/patches/0005-mir-paste-clipboard-data-from-content-hub.patch:
* debian/patches/0006-mir-properly-handle-empty-clipboard.patch:
* debian/patches/0031-mir-fix-compile-time-warnings.patch:
* debian/patches/0032-mir-use-modal-window-hint.patch:
* debian/patches/0036-mir-use-mir_surface_spec_set_placement-for-menus.patch:
* debian/patches/0037-mir-handle-surface-placement-events.patch:
  - Add upstream patches from gtk-3-22 branch

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2017-01-23 14:44:32 +0000
3+++ debian/changelog 2017-02-08 17:37:49 +0000
4@@ -1,3 +1,23 @@
5+gtk+3.0 (3.22.7-1ubuntu3) zesty; urgency=medium
6+
7+ * debian/control:
8+ * debian/control.in:
9+ - Build depend on libcontent-hub-glib-dev
10+ * debian/patches/series:
11+ * debian/patches/0001-mir-implement-window-properties.patch:
12+ * debian/patches/0002-mir-track-focused-window.patch:
13+ * debian/patches/0003-mir-connect-to-content-hub.patch:
14+ * debian/patches/0004-mir-copy-clipboard-data-to-content-hub.patch:
15+ * debian/patches/0005-mir-paste-clipboard-data-from-content-hub.patch:
16+ * debian/patches/0006-mir-properly-handle-empty-clipboard.patch:
17+ * debian/patches/0031-mir-fix-compile-time-warnings.patch:
18+ * debian/patches/0032-mir-use-modal-window-hint.patch:
19+ * debian/patches/0036-mir-use-mir_surface_spec_set_placement-for-menus.patch:
20+ * debian/patches/0037-mir-handle-surface-placement-events.patch:
21+ - Add upstream patches from gtk-3-22 branch
22+
23+ -- William Hua <william.hua@canonical.com> Wed, 08 Feb 2017 10:27:45 -0500
24+
25 gtk+3.0 (3.22.7-1ubuntu2) zesty; urgency=medium
26
27 * Restore gtksocket-unscale-before-sending-configurenotify.patch:
28
29=== modified file 'debian/control'
30--- debian/control 2016-10-24 16:41:31 +0000
31+++ debian/control 2017-02-08 17:37:49 +0000
32@@ -52,7 +52,8 @@
33 xsltproc,
34 xvfb <!nocheck>,
35 libmirclient-dev (>= 0.13.3),
36- libmircookie-dev (>= 0.17.0)
37+ libmircookie-dev (>= 0.17.0),
38+ libcontent-hub-glib-dev,
39 Build-Depends-Indep: libglib2.0-doc,
40 libatk1.0-doc,
41 libpango1.0-doc,
42
43=== modified file 'debian/control.in'
44--- debian/control.in 2016-10-24 16:41:31 +0000
45+++ debian/control.in 2017-02-08 17:37:49 +0000
46@@ -52,7 +52,8 @@
47 xsltproc,
48 xvfb <!nocheck>,
49 libmirclient-dev (>= 0.13.3),
50- libmircookie-dev (>= 0.17.0)
51+ libmircookie-dev (>= 0.17.0),
52+ libcontent-hub-glib-dev,
53 Build-Depends-Indep: libglib2.0-doc,
54 libatk1.0-doc,
55 libpango1.0-doc,
56
57=== added file 'debian/patches/0001-mir-implement-window-properties.patch'
58--- debian/patches/0001-mir-implement-window-properties.patch 1970-01-01 00:00:00 +0000
59+++ debian/patches/0001-mir-implement-window-properties.patch 2017-02-08 17:37:49 +0000
60@@ -0,0 +1,244 @@
61+From b6baa088dccecb25130d056f33d8078d198dd2d7 Mon Sep 17 00:00:00 2001
62+From: William Hua <william.hua@canonical.com>
63+Date: Tue, 11 Oct 2016 19:06:12 -0400
64+Subject: [PATCH 01/38] mir: implement window properties
65+
66+https://bugzilla.gnome.org/show_bug.cgi?id=775732
67+---
68+ gdk/mir/gdkmirwindowimpl.c | 179 +++++++++++++++++++++++++++++++++++++++++----
69+ 1 file changed, 163 insertions(+), 16 deletions(-)
70+
71+diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
72+index a7be39c..48e66ca 100644
73+--- a/gdk/mir/gdkmirwindowimpl.c
74++++ b/gdk/mir/gdkmirwindowimpl.c
75+@@ -36,12 +36,45 @@
76+
77+ #define MAX_EGL_ATTRS 30
78+
79++typedef struct
80++{
81++ GdkAtom type;
82++ GArray *array;
83++} GdkMirProperty;
84++
85++static GdkMirProperty *
86++gdk_mir_property_new (GdkAtom type,
87++ guint format,
88++ guint capacity)
89++{
90++ GdkMirProperty *property = g_slice_new (GdkMirProperty);
91++
92++ property->type = type;
93++ property->array = g_array_sized_new (TRUE, FALSE, format, capacity);
94++
95++ return property;
96++}
97++
98++static void
99++gdk_mir_property_free (gpointer data)
100++{
101++ GdkMirProperty *property = data;
102++
103++ if (!property)
104++ return;
105++
106++ g_array_unref (property->array);
107++ g_slice_free (GdkMirProperty, property);
108++}
109++
110+ typedef struct _GdkMirWindowImplClass GdkMirWindowImplClass;
111+
112+ struct _GdkMirWindowImpl
113+ {
114+ GdkWindowImpl parent_instance;
115+
116++ GHashTable *properties;
117++
118+ /* Window we are temporary for */
119+ GdkWindow *transient_for;
120+ gint transient_x;
121+@@ -233,6 +266,7 @@ _gdk_mir_window_impl_get_cursor_state (GdkMirWindowImpl *impl,
122+ static void
123+ gdk_mir_window_impl_init (GdkMirWindowImpl *impl)
124+ {
125++ impl->properties = g_hash_table_new_full (NULL, NULL, NULL, gdk_mir_property_free);
126+ impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
127+ impl->surface_state = mir_surface_state_unknown;
128+ impl->output_scale = 1;
129+@@ -687,6 +721,8 @@ gdk_mir_window_impl_finalize (GObject *object)
130+ if (impl->cairo_surface)
131+ cairo_surface_destroy (impl->cairo_surface);
132+
133++ g_clear_pointer (&impl->properties, g_hash_table_unref);
134++
135+ G_OBJECT_CLASS (gdk_mir_window_impl_parent_class)->finalize (object);
136+ }
137+
138+@@ -1482,19 +1518,79 @@ gdk_mir_window_impl_simulate_button (GdkWindow *window,
139+ }
140+
141+ static gboolean
142+-gdk_mir_window_impl_get_property (GdkWindow *window,
143+- GdkAtom property,
144+- GdkAtom type,
145+- gulong offset,
146+- gulong length,
147+- gint pdelete,
148+- GdkAtom *actual_property_type,
149+- gint *actual_format_type,
150+- gint *actual_length,
151+- guchar **data)
152+-{
153+- //g_printerr ("gdk_mir_window_impl_get_property window=%p\n", window);
154+- return FALSE;
155++gdk_mir_window_impl_get_property (GdkWindow *window,
156++ GdkAtom property,
157++ GdkAtom type,
158++ gulong offset,
159++ gulong length,
160++ gint pdelete,
161++ GdkAtom *actual_type,
162++ gint *actual_format,
163++ gint *actual_length,
164++ guchar **data)
165++{
166++ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
167++ GdkMirProperty *mir_property;
168++ GdkAtom dummy_actual_type;
169++ gint dummy_actual_format;
170++ gint dummy_actual_length;
171++ guint width;
172++
173++ if (!actual_type)
174++ actual_type = &dummy_actual_type;
175++ if (!actual_format)
176++ actual_format = &dummy_actual_format;
177++ if (!actual_length)
178++ actual_length = &dummy_actual_length;
179++
180++ *actual_type = GDK_NONE;
181++ *actual_format = 0;
182++ *actual_length = 0;
183++
184++ if (data)
185++ *data = NULL;
186++
187++ mir_property = g_hash_table_lookup (impl->properties, property);
188++
189++ if (!mir_property)
190++ return FALSE;
191++
192++ width = g_array_get_element_size (mir_property->array);
193++ *actual_type = mir_property->type;
194++ *actual_format = 8 * width;
195++
196++ /* ICCCM 2.7: GdkAtoms can be 64-bit, but ATOMs and ATOM_PAIRs have format 32 */
197++ if (*actual_type == GDK_SELECTION_TYPE_ATOM || *actual_type == gdk_atom_intern_static_string ("ATOM_PAIR"))
198++ *actual_format = 32;
199++
200++ if (type != GDK_NONE && type != mir_property->type)
201++ return FALSE;
202++
203++ offset *= 4;
204++
205++ /* round up to next nearest multiple of width */
206++ if (length < G_MAXULONG - width + 1)
207++ length = (length - 1 + width) / width * width;
208++ else
209++ length = G_MAXULONG / width * width;
210++
211++ /* we're skipping the first offset bytes */
212++ if (length > mir_property->array->len * width - offset)
213++ length = mir_property->array->len * width - offset;
214++
215++ /* leave room for null terminator */
216++ if (length > G_MAXULONG - width)
217++ length -= width;
218++
219++ *actual_length = length;
220++
221++ if (data)
222++ {
223++ *data = g_memdup (mir_property->array->data + offset, length + width);
224++ memset (*data + length, 0, width);
225++ }
226++
227++ return TRUE;
228+ }
229+
230+ static void
231+@@ -1504,16 +1600,67 @@ gdk_mir_window_impl_change_property (GdkWindow *window,
232+ gint format,
233+ GdkPropMode mode,
234+ const guchar *data,
235+- gint nelements)
236++ gint n_elements)
237+ {
238+- //g_printerr ("gdk_mir_window_impl_change_property window=%p\n", window);
239++ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
240++ GdkMirProperty *mir_property;
241++ GdkEvent *event;
242++
243++ /* ICCCM 2.7: ATOMs and ATOM_PAIRs have format 32, but GdkAtoms can be 64-bit */
244++ if (type == GDK_SELECTION_TYPE_ATOM || type == gdk_atom_intern_static_string ("ATOM_PAIR"))
245++ format = 8 * sizeof (GdkAtom);
246++
247++ if (mode != GDK_PROP_MODE_REPLACE)
248++ mir_property = g_hash_table_lookup (impl->properties, property);
249++ else
250++ mir_property = NULL;
251++
252++ if (!mir_property)
253++ {
254++ /* format is measured in bits, but we need to know this in bytes */
255++ mir_property = gdk_mir_property_new (type, format / 8, n_elements);
256++ g_hash_table_insert (impl->properties, property, mir_property);
257++ }
258++
259++ /* format is measured in bits, but we need to know this in bytes */
260++ if (type != mir_property->type || format / 8 != g_array_get_element_size (mir_property->array))
261++ return;
262++
263++ if (mode == GDK_PROP_MODE_PREPEND)
264++ g_array_prepend_vals (mir_property->array, data, n_elements);
265++ else
266++ g_array_append_vals (mir_property->array, data, n_elements);
267++
268++ event = gdk_event_new (GDK_PROPERTY_NOTIFY);
269++ event->property.window = g_object_ref (window);
270++ event->property.send_event = FALSE;
271++ event->property.atom = property;
272++ event->property.time = GDK_CURRENT_TIME;
273++ event->property.state = GDK_PROPERTY_NEW_VALUE;
274++
275++ gdk_event_put (event);
276++ gdk_event_free (event);
277+ }
278+
279+ static void
280+ gdk_mir_window_impl_delete_property (GdkWindow *window,
281+ GdkAtom property)
282+ {
283+- //g_printerr ("gdk_mir_window_impl_delete_property window=%p\n", window);
284++ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
285++ GdkEvent *event;
286++
287++ if (g_hash_table_remove (impl->properties, property))
288++ {
289++ event = gdk_event_new (GDK_PROPERTY_NOTIFY);
290++ event->property.window = g_object_ref (window);
291++ event->property.send_event = FALSE;
292++ event->property.atom = property;
293++ event->property.time = GDK_CURRENT_TIME;
294++ event->property.state = GDK_PROPERTY_DELETE;
295++
296++ gdk_event_put (event);
297++ gdk_event_free (event);
298++ }
299+ }
300+
301+ static gint
302+--
303+2.10.2
304+
305
306=== added file 'debian/patches/0002-mir-track-focused-window.patch'
307--- debian/patches/0002-mir-track-focused-window.patch 1970-01-01 00:00:00 +0000
308+++ debian/patches/0002-mir-track-focused-window.patch 2017-02-08 17:37:49 +0000
309@@ -0,0 +1,91 @@
310+From 0acb58b40fbc158f94486195e35088f610071583 Mon Sep 17 00:00:00 2001
311+From: William Hua <william.hua@canonical.com>
312+Date: Fri, 14 Oct 2016 17:00:34 -0400
313+Subject: [PATCH 02/38] mir: track focused window
314+
315+https://bugzilla.gnome.org/show_bug.cgi?id=775732
316+---
317+ gdk/mir/gdkmir-private.h | 4 ++++
318+ gdk/mir/gdkmirdisplay.c | 21 +++++++++++++++++++++
319+ gdk/mir/gdkmireventsource.c | 10 ++++++++--
320+ 3 files changed, 33 insertions(+), 2 deletions(-)
321+
322+diff --git a/gdk/mir/gdkmir-private.h b/gdk/mir/gdkmir-private.h
323+index 38f1d7a..7e3893c 100644
324+--- a/gdk/mir/gdkmir-private.h
325++++ b/gdk/mir/gdkmir-private.h
326+@@ -107,6 +107,10 @@ void _gdk_mir_event_source_queue (GdkMirWindowReference *window_ref, const MirEv
327+
328+ MirPixelFormat _gdk_mir_display_get_pixel_format (GdkDisplay *display, MirBufferUsage usage);
329+
330++void _gdk_mir_display_focus_window (GdkDisplay *display, GdkWindow *window);
331++
332++void _gdk_mir_display_unfocus_window (GdkDisplay *display, GdkWindow *window);
333++
334+ gboolean _gdk_mir_display_init_egl_display (GdkDisplay *display);
335+
336+ EGLDisplay _gdk_mir_display_get_egl_display (GdkDisplay *display);
337+diff --git a/gdk/mir/gdkmirdisplay.c b/gdk/mir/gdkmirdisplay.c
338+index eea892c..89cfad2 100644
339+--- a/gdk/mir/gdkmirdisplay.c
340++++ b/gdk/mir/gdkmirdisplay.c
341+@@ -47,6 +47,8 @@ typedef struct GdkMirDisplay
342+
343+ GdkKeymap *keymap;
344+
345++ GdkWindow *focused_window;
346++
347+ MirPixelFormat sw_pixel_format;
348+ MirPixelFormat hw_pixel_format;
349+
350+@@ -582,6 +584,25 @@ _gdk_mir_display_get_pixel_format (GdkDisplay *display,
351+ return mir_dpy->sw_pixel_format;
352+ }
353+
354++void
355++_gdk_mir_display_focus_window (GdkDisplay *display,
356++ GdkWindow *window)
357++{
358++ GdkMirDisplay *mir_display = GDK_MIR_DISPLAY (display);
359++
360++ g_set_object (&mir_display->focused_window, window);
361++}
362++
363++void
364++_gdk_mir_display_unfocus_window (GdkDisplay *display,
365++ GdkWindow *window)
366++{
367++ GdkMirDisplay *mir_display = GDK_MIR_DISPLAY (display);
368++
369++ if (window == mir_display->focused_window)
370++ g_clear_object (&mir_display->focused_window);
371++}
372++
373+ gboolean
374+ _gdk_mir_display_init_egl_display (GdkDisplay *display)
375+ {
376+diff --git a/gdk/mir/gdkmireventsource.c b/gdk/mir/gdkmireventsource.c
377+index 8c7e106..a2a1a12 100644
378+--- a/gdk/mir/gdkmireventsource.c
379++++ b/gdk/mir/gdkmireventsource.c
380+@@ -240,9 +240,15 @@ generate_focus_event (GdkWindow *window, gboolean focused)
381+ GdkEvent *event;
382+
383+ if (focused)
384+- gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FOCUSED);
385++ {
386++ gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FOCUSED);
387++ _gdk_mir_display_focus_window (gdk_window_get_display (window), window);
388++ }
389+ else
390+- gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FOCUSED, 0);
391++ {
392++ gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FOCUSED, 0);
393++ _gdk_mir_display_unfocus_window (gdk_window_get_display (window), window);
394++ }
395+
396+ event = gdk_event_new (GDK_FOCUS_CHANGE);
397+ event->focus_change.send_event = FALSE;
398+--
399+2.10.2
400+
401
402=== added file 'debian/patches/0003-mir-connect-to-content-hub.patch'
403--- debian/patches/0003-mir-connect-to-content-hub.patch 1970-01-01 00:00:00 +0000
404+++ debian/patches/0003-mir-connect-to-content-hub.patch 2017-02-08 17:37:49 +0000
405@@ -0,0 +1,108 @@
406+From 210d1279e5811ae18b0bad13f16a97c7ec98598e Mon Sep 17 00:00:00 2001
407+From: William Hua <william.hua@canonical.com>
408+Date: Tue, 11 Oct 2016 16:53:48 -0400
409+Subject: [PATCH 03/38] mir: connect to content-hub
410+
411+https://bugzilla.gnome.org/show_bug.cgi?id=775732
412+---
413+ configure.ac | 2 +-
414+ gdk/mir/gdkmirdisplay.c | 42 ++++++++++++++++++++++++++++++++++++++++++
415+ 2 files changed, 43 insertions(+), 1 deletion(-)
416+
417+diff --git a/configure.ac b/configure.ac
418+index ea609b3..000e37a 100644
419+--- a/configure.ac
420++++ b/configure.ac
421+@@ -464,7 +464,7 @@ else
422+ AM_CONDITIONAL(USE_WAYLAND, false)
423+ fi
424+
425+-MIR_DEPENDENCIES="mirclient >= mirclient_required_version mircookie >= mircookie_required_version"
426++MIR_DEPENDENCIES="mirclient >= mirclient_required_version mircookie >= mircookie_required_version libcontent-hub-glib"
427+ if test "$enable_mir_backend" = "maybe" ; then
428+ PKG_CHECK_EXISTS($MIR_DEPENDENCIES, [have_mir_deps=yes], [have_mir_deps=no])
429+ AC_MSG_CHECKING([for MIR_DEPENDENCIES])
430+diff --git a/gdk/mir/gdkmirdisplay.c b/gdk/mir/gdkmirdisplay.c
431+index 89cfad2..718ab60 100644
432+--- a/gdk/mir/gdkmirdisplay.c
433++++ b/gdk/mir/gdkmirdisplay.c
434+@@ -23,6 +23,8 @@
435+ #include "gdkmir.h"
436+ #include "gdkmir-private.h"
437+
438++#include <com/ubuntu/content/glib/content-hub-glib.h>
439++
440+ #define GDK_TYPE_DISPLAY_MIR (gdk_mir_display_get_type ())
441+ #define GDK_MIR_DISPLAY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DISPLAY_MIR, GdkMirDisplay))
442+ #define GDK_MIR_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DISPLAY_MIR, GdkMirDisplayClass))
443+@@ -57,6 +59,9 @@ typedef struct GdkMirDisplay
444+ guint have_egl_buffer_age : 1;
445+ guint have_egl_swap_buffers_with_damage : 1;
446+ guint have_egl_surfaceless_context : 1;
447++
448++ ContentHubService *content_service;
449++ ContentHubHandler *content_handler;
450+ } GdkMirDisplay;
451+
452+ typedef struct GdkMirDisplayClass
453+@@ -108,6 +113,7 @@ _gdk_mir_display_open (const gchar *display_name)
454+ MirConnection *connection;
455+ MirPixelFormat sw_pixel_format, hw_pixel_format;
456+ GdkMirDisplay *display;
457++ GDBusConnection *session;
458+
459+ //g_printerr ("gdk_mir_display_open\n");
460+
461+@@ -140,6 +146,39 @@ _gdk_mir_display_open (const gchar *display_name)
462+ display->sw_pixel_format = sw_pixel_format;
463+ display->hw_pixel_format = hw_pixel_format;
464+
465++ session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
466++
467++ display->content_service = content_hub_service_proxy_new_sync (
468++ session,
469++ G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
470++ "com.ubuntu.content.dbus.Service",
471++ "/",
472++ NULL,
473++ NULL);
474++
475++ display->content_handler = content_hub_handler_skeleton_new ();
476++
477++ g_dbus_interface_skeleton_export (
478++ G_DBUS_INTERFACE_SKELETON (display->content_handler),
479++ session,
480++ "/org/gnome/gtk/content/handler",
481++ NULL);
482++
483++ g_object_unref (session);
484++
485++ content_hub_service_call_register_import_export_handler_sync (
486++ display->content_service,
487++ g_application_get_application_id (g_application_get_default ()),
488++ "/org/gnome/gtk/content/handler",
489++ NULL,
490++ NULL);
491++
492++ content_hub_service_call_handler_active_sync (
493++ display->content_service,
494++ g_application_get_application_id (g_application_get_default ()),
495++ NULL,
496++ NULL);
497++
498+ g_signal_emit_by_name (display, "opened");
499+
500+ return GDK_DISPLAY (display);
501+@@ -175,6 +214,9 @@ gdk_mir_display_dispose (GObject *object)
502+ {
503+ GdkMirDisplay *display = GDK_MIR_DISPLAY (object);
504+
505++ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (display->content_handler));
506++ g_clear_object (&display->content_handler);
507++ g_clear_object (&display->content_service);
508+ g_clear_object (&display->screen);
509+ g_clear_object (&display->keymap);
510+ g_clear_pointer (&display->event_source, g_source_unref);
511+--
512+2.10.2
513+
514
515=== added file 'debian/patches/0004-mir-copy-clipboard-data-to-content-hub.patch'
516--- debian/patches/0004-mir-copy-clipboard-data-to-content-hub.patch 1970-01-01 00:00:00 +0000
517+++ debian/patches/0004-mir-copy-clipboard-data-to-content-hub.patch 2017-02-08 17:37:49 +0000
518@@ -0,0 +1,292 @@
519+From 5c4c3f1afd9a56644c1d204df3a9f5f1526ffa38 Mon Sep 17 00:00:00 2001
520+From: William Hua <william.hua@canonical.com>
521+Date: Wed, 12 Oct 2016 16:56:01 -0400
522+Subject: [PATCH 04/38] mir: copy clipboard data to content-hub
523+
524+https://bugzilla.gnome.org/show_bug.cgi?id=775732
525+---
526+ gdk/mir/gdkmir-private.h | 5 ++
527+ gdk/mir/gdkmirdisplay.c | 60 +++++++++++++++++-
528+ gdk/mir/gdkmirwindowimpl.c | 150 ++++++++++++++++++++++++++++++++++++++++++++-
529+ 3 files changed, 212 insertions(+), 3 deletions(-)
530+
531+diff --git a/gdk/mir/gdkmir-private.h b/gdk/mir/gdkmir-private.h
532+index 7e3893c..a677dec 100644
533+--- a/gdk/mir/gdkmir-private.h
534++++ b/gdk/mir/gdkmir-private.h
535+@@ -111,6 +111,11 @@ void _gdk_mir_display_focus_window (GdkDisplay *display, GdkWindow *window);
536+
537+ void _gdk_mir_display_unfocus_window (GdkDisplay *display, GdkWindow *window);
538+
539++void _gdk_mir_display_create_paste (GdkDisplay *display,
540++ const gchar * const *paste_formats,
541++ gconstpointer paste_data,
542++ gsize paste_size);
543++
544+ gboolean _gdk_mir_display_init_egl_display (GdkDisplay *display);
545+
546+ EGLDisplay _gdk_mir_display_get_egl_display (GdkDisplay *display);
547+diff --git a/gdk/mir/gdkmirdisplay.c b/gdk/mir/gdkmirdisplay.c
548+index 718ab60..3dd3798 100644
549+--- a/gdk/mir/gdkmirdisplay.c
550++++ b/gdk/mir/gdkmirdisplay.c
551+@@ -504,7 +504,28 @@ gdk_mir_display_set_selection_owner (GdkDisplay *display,
552+ guint32 time,
553+ gboolean send_event)
554+ {
555+- //g_printerr ("gdk_mir_display_set_selection_owner\n");
556++ GdkEvent *event;
557++
558++ if (selection == GDK_SELECTION_CLIPBOARD)
559++ {
560++ if (owner)
561++ {
562++ event = gdk_event_new (GDK_SELECTION_REQUEST);
563++ event->selection.window = g_object_ref (owner);
564++ event->selection.send_event = FALSE;
565++ event->selection.selection = selection;
566++ event->selection.target = gdk_atom_intern_static_string ("TARGETS");
567++ event->selection.property = gdk_atom_intern_static_string ("AVAILABLE_TARGETS");
568++ event->selection.time = GDK_CURRENT_TIME;
569++ event->selection.requestor = g_object_ref (owner);
570++
571++ gdk_event_put (event);
572++ gdk_event_free (event);
573++
574++ return TRUE;
575++ }
576++ }
577++
578+ return FALSE;
579+ }
580+
581+@@ -645,6 +666,43 @@ _gdk_mir_display_unfocus_window (GdkDisplay *display,
582+ g_clear_object (&mir_display->focused_window);
583+ }
584+
585++void
586++_gdk_mir_display_create_paste (GdkDisplay *display,
587++ const gchar * const *paste_formats,
588++ gconstpointer paste_data,
589++ gsize paste_size)
590++{
591++ GdkMirDisplay *mir_display = GDK_MIR_DISPLAY (display);
592++ MirSurface *surface;
593++ MirPersistentId *persistent_id;
594++
595++ if (!mir_display->focused_window)
596++ return;
597++
598++ surface = gdk_mir_window_get_mir_surface (mir_display->focused_window);
599++
600++ if (!surface)
601++ return;
602++
603++ persistent_id = mir_surface_request_persistent_id_sync (surface);
604++
605++ if (!persistent_id)
606++ return;
607++
608++ if (mir_persistent_id_is_valid (persistent_id))
609++ content_hub_service_call_create_paste_sync (
610++ mir_display->content_service,
611++ g_application_get_application_id (g_application_get_default ()),
612++ mir_persistent_id_as_string (persistent_id),
613++ g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, paste_data, paste_size, sizeof (guchar)),
614++ paste_formats,
615++ NULL,
616++ NULL,
617++ NULL);
618++
619++ mir_persistent_id_release (persistent_id);
620++}
621++
622+ gboolean
623+ _gdk_mir_display_init_egl_display (GdkDisplay *display)
624+ {
625+diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
626+index 48e66ca..8a15816 100644
627+--- a/gdk/mir/gdkmirwindowimpl.c
628++++ b/gdk/mir/gdkmirwindowimpl.c
629+@@ -1594,6 +1594,140 @@ gdk_mir_window_impl_get_property (GdkWindow *window,
630+ }
631+
632+ static void
633++request_targets (GdkWindow *window,
634++ const GdkAtom *available_targets,
635++ gint n_available_targets)
636++{
637++ GArray *requested_targets;
638++ GdkAtom target_pair[2];
639++ gchar *target_location;
640++ GdkEvent *event;
641++ gint i;
642++
643++ requested_targets = g_array_sized_new (TRUE, FALSE, sizeof (GdkAtom), 2 * n_available_targets);
644++
645++ for (i = 0; i < n_available_targets; i++)
646++ {
647++ target_pair[0] = available_targets[i];
648++
649++ if (target_pair[0] == gdk_atom_intern_static_string ("TIMESTAMP") ||
650++ target_pair[0] == gdk_atom_intern_static_string ("TARGETS") ||
651++ target_pair[0] == gdk_atom_intern_static_string ("MULTIPLE") ||
652++ target_pair[0] == gdk_atom_intern_static_string ("SAVE_TARGETS"))
653++ continue;
654++
655++ target_location = g_strdup_printf ("REQUESTED_TARGET_U%u", requested_targets->len / 2);
656++ target_pair[1] = gdk_atom_intern (target_location, FALSE);
657++ g_free (target_location);
658++
659++ g_array_append_vals (requested_targets, target_pair, 2);
660++ }
661++
662++ gdk_property_delete (window, gdk_atom_intern_static_string ("AVAILABLE_TARGETS"));
663++ gdk_property_delete (window, gdk_atom_intern_static_string ("REQUESTED_TARGETS"));
664++
665++ gdk_property_change (window,
666++ gdk_atom_intern_static_string ("REQUESTED_TARGETS"),
667++ GDK_SELECTION_TYPE_ATOM,
668++ 8 * sizeof (GdkAtom),
669++ GDK_PROP_MODE_REPLACE,
670++ (const guchar *) requested_targets->data,
671++ requested_targets->len);
672++
673++ g_array_unref (requested_targets);
674++
675++ event = gdk_event_new (GDK_SELECTION_REQUEST);
676++ event->selection.window = g_object_ref (window);
677++ event->selection.send_event = FALSE;
678++ event->selection.selection = GDK_SELECTION_CLIPBOARD;
679++ event->selection.target = gdk_atom_intern_static_string ("MULTIPLE");
680++ event->selection.property = gdk_atom_intern_static_string ("REQUESTED_TARGETS");
681++ event->selection.time = GDK_CURRENT_TIME;
682++ event->selection.requestor = g_object_ref (window);
683++
684++ gdk_event_put (event);
685++ gdk_event_free (event);
686++}
687++
688++static void
689++create_paste (GdkWindow *window,
690++ const GdkAtom *requested_targets,
691++ gint n_requested_targets)
692++{
693++ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
694++ GPtrArray *paste_formats;
695++ GArray *paste_header;
696++ GByteArray *paste_data;
697++ gint sizes[4];
698++ GdkMirProperty *mir_property;
699++ const gchar *paste_format;
700++ gint i;
701++
702++ paste_formats = g_ptr_array_new_full (n_requested_targets, g_free);
703++ paste_header = g_array_sized_new (FALSE, FALSE, sizeof (gint), 1 + 4 * n_requested_targets);
704++ paste_data = g_byte_array_new ();
705++
706++ g_array_append_val (paste_header, sizes[0]);
707++
708++ for (i = 0; i < n_requested_targets; i++)
709++ {
710++ if (requested_targets[i] == GDK_NONE)
711++ continue;
712++
713++ mir_property = g_hash_table_lookup (impl->properties, requested_targets[i]);
714++
715++ if (!mir_property)
716++ continue;
717++
718++ paste_format = _gdk_atom_name_const (mir_property->type);
719++
720++ /* skip non-MIME targets */
721++ if (!strchr (paste_format, '/'))
722++ {
723++ g_hash_table_remove (impl->properties, requested_targets[i]);
724++ continue;
725++ }
726++
727++ sizes[0] = paste_data->len;
728++ sizes[1] = strlen (paste_format);
729++ sizes[2] = sizes[0] + sizes[1];
730++ sizes[3] = mir_property->array->len * g_array_get_element_size (mir_property->array);
731++
732++ g_ptr_array_add (paste_formats, g_strdup (paste_format));
733++ g_array_append_vals (paste_header, sizes, 4);
734++ g_byte_array_append (paste_data, (const guint8 *) paste_format, sizes[1]);
735++ g_byte_array_append (paste_data, (const guint8 *) mir_property->array->data, sizes[3]);
736++
737++ g_hash_table_remove (impl->properties, requested_targets[i]);
738++ }
739++
740++ gdk_property_delete (window, gdk_atom_intern_static_string ("REQUESTED_TARGETS"));
741++
742++ g_array_index (paste_header, gint, 0) = paste_formats->len;
743++
744++ for (i = 0; i < paste_formats->len; i++)
745++ {
746++ g_array_index (paste_header, gint, 1 + 4 * i) += paste_header->len * sizeof (gint);
747++ g_array_index (paste_header, gint, 3 + 4 * i) += paste_header->len * sizeof (gint);
748++ }
749++
750++ g_byte_array_prepend (paste_data,
751++ (const guint8 *) paste_header->data,
752++ paste_header->len * g_array_get_element_size (paste_header));
753++
754++ g_ptr_array_add (paste_formats, NULL);
755++
756++ _gdk_mir_display_create_paste (gdk_window_get_display (window),
757++ (const gchar * const *) paste_formats->pdata,
758++ paste_data->data,
759++ paste_data->len);
760++
761++ g_byte_array_unref (paste_data);
762++ g_array_unref (paste_header);
763++ g_ptr_array_unref (paste_formats);
764++}
765++
766++static void
767+ gdk_mir_window_impl_change_property (GdkWindow *window,
768+ GdkAtom property,
769+ GdkAtom type,
770+@@ -1604,6 +1738,7 @@ gdk_mir_window_impl_change_property (GdkWindow *window,
771+ {
772+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
773+ GdkMirProperty *mir_property;
774++ gboolean existed;
775+ GdkEvent *event;
776+
777+ /* ICCCM 2.7: ATOMs and ATOM_PAIRs have format 32, but GdkAtoms can be 64-bit */
778+@@ -1611,9 +1746,15 @@ gdk_mir_window_impl_change_property (GdkWindow *window,
779+ format = 8 * sizeof (GdkAtom);
780+
781+ if (mode != GDK_PROP_MODE_REPLACE)
782+- mir_property = g_hash_table_lookup (impl->properties, property);
783++ {
784++ mir_property = g_hash_table_lookup (impl->properties, property);
785++ existed = mir_property != NULL;
786++ }
787+ else
788+- mir_property = NULL;
789++ {
790++ mir_property = NULL;
791++ existed = g_hash_table_contains (impl->properties, property);
792++ }
793+
794+ if (!mir_property)
795+ {
796+@@ -1640,6 +1781,11 @@ gdk_mir_window_impl_change_property (GdkWindow *window,
797+
798+ gdk_event_put (event);
799+ gdk_event_free (event);
800++
801++ if (property == gdk_atom_intern_static_string ("AVAILABLE_TARGETS"))
802++ request_targets (window, (const GdkAtom *) data, n_elements);
803++ else if (property == gdk_atom_intern_static_string ("REQUESTED_TARGETS") && existed)
804++ create_paste (window, (const GdkAtom *) data, n_elements);
805+ }
806+
807+ static void
808+--
809+2.10.2
810+
811
812=== added file 'debian/patches/0005-mir-paste-clipboard-data-from-content-hub.patch'
813--- debian/patches/0005-mir-paste-clipboard-data-from-content-hub.patch 1970-01-01 00:00:00 +0000
814+++ debian/patches/0005-mir-paste-clipboard-data-from-content-hub.patch 2017-02-08 17:37:49 +0000
815@@ -0,0 +1,415 @@
816+From 41732391d8b93478d4b63d63f9c3cc5bbf124a2a Mon Sep 17 00:00:00 2001
817+From: William Hua <william.hua@canonical.com>
818+Date: Sat, 15 Oct 2016 22:19:59 +0200
819+Subject: [PATCH 05/38] mir: paste clipboard data from content-hub
820+
821+https://bugzilla.gnome.org/show_bug.cgi?id=775732
822+---
823+ gdk/mir/gdkmirdisplay.c | 339 +++++++++++++++++++++++++++++++++++++++++++++++-
824+ 1 file changed, 335 insertions(+), 4 deletions(-)
825+
826+diff --git a/gdk/mir/gdkmirdisplay.c b/gdk/mir/gdkmirdisplay.c
827+index 3dd3798..21967ac 100644
828+--- a/gdk/mir/gdkmirdisplay.c
829++++ b/gdk/mir/gdkmirdisplay.c
830+@@ -23,6 +23,8 @@
831+ #include "gdkmir.h"
832+ #include "gdkmir-private.h"
833+
834++#include <string.h>
835++
836+ #include <com/ubuntu/content/glib/content-hub-glib.h>
837+
838+ #define GDK_TYPE_DISPLAY_MIR (gdk_mir_display_get_type ())
839+@@ -62,6 +64,7 @@ typedef struct GdkMirDisplay
840+
841+ ContentHubService *content_service;
842+ ContentHubHandler *content_handler;
843++ GVariant *paste_data;
844+ } GdkMirDisplay;
845+
846+ typedef struct GdkMirDisplayClass
847+@@ -107,6 +110,13 @@ static void get_pixel_formats (MirConnection *, MirPixelFormat *sw, MirPixelForm
848+
849+ G_DEFINE_TYPE (GdkMirDisplay, gdk_mir_display, GDK_TYPE_DISPLAY)
850+
851++static void
852++pasteboard_changed_cb (GdkMirDisplay *display,
853++ gpointer user_data)
854++{
855++ g_clear_pointer (&display->paste_data, g_variant_unref);
856++}
857++
858+ GdkDisplay *
859+ _gdk_mir_display_open (const gchar *display_name)
860+ {
861+@@ -156,6 +166,12 @@ _gdk_mir_display_open (const gchar *display_name)
862+ NULL,
863+ NULL);
864+
865++ g_signal_connect_swapped (
866++ display->content_service,
867++ "pasteboard-changed",
868++ G_CALLBACK (pasteboard_changed_cb),
869++ display);
870++
871+ display->content_handler = content_hub_handler_skeleton_new ();
872+
873+ g_dbus_interface_skeleton_export (
874+@@ -214,6 +230,7 @@ gdk_mir_display_dispose (GObject *object)
875+ {
876+ GdkMirDisplay *display = GDK_MIR_DISPLAY (object);
877+
878++ g_clear_pointer (&display->paste_data, g_variant_unref);
879+ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (display->content_handler));
880+ g_clear_object (&display->content_handler);
881+ g_clear_object (&display->content_service);
882+@@ -547,10 +564,255 @@ gdk_mir_display_get_selection_property (GdkDisplay *display,
883+ GdkAtom *ret_type,
884+ gint *ret_format)
885+ {
886+- //g_printerr ("gdk_mir_display_get_selection_property\n");
887++ gint length;
888++
889++ gdk_property_get (requestor,
890++ gdk_atom_intern_static_string ("GDK_SELECTION"),
891++ GDK_NONE,
892++ 0,
893++ G_MAXULONG,
894++ FALSE,
895++ ret_type,
896++ ret_format,
897++ &length,
898++ data);
899++
900++ return length;
901++}
902++
903++static gint
904++get_format_score (const gchar *format,
905++ GdkAtom target,
906++ GdkAtom *out_type,
907++ gint *out_size)
908++{
909++ const gchar *target_string;
910++ GdkAtom dummy_type;
911++ gint dummy_size;
912++
913++ target_string = _gdk_atom_name_const (target);
914++
915++ if (!out_type)
916++ out_type = &dummy_type;
917++
918++ if (!out_size)
919++ out_size = &dummy_size;
920++
921++ if (!g_ascii_strcasecmp (format, target_string))
922++ {
923++ *out_type = GDK_SELECTION_TYPE_STRING;
924++ *out_size = sizeof (guchar);
925++
926++ return G_MAXINT;
927++ }
928++
929++ if (target == gdk_atom_intern_static_string ("UTF8_STRING"))
930++ return get_format_score (format, gdk_atom_intern_static_string ("text/plain;charset=utf-8"), out_type, out_size);
931++
932++ /* TODO: use best media type for COMPOUND_TEXT target */
933++ if (target == gdk_atom_intern_static_string ("COMPOUND_TEXT"))
934++ return get_format_score (format, gdk_atom_intern_static_string ("text/plain;charset=utf-8"), out_type, out_size);
935++
936++ if (target == GDK_TARGET_STRING)
937++ return get_format_score (format, gdk_atom_intern_static_string ("text/plain;charset=iso-8859-1"), out_type, out_size);
938++
939++ if (target == gdk_atom_intern_static_string ("GTK_TEXT_BUFFER_CONTENTS"))
940++ return get_format_score (format, gdk_atom_intern_static_string ("text/plain;charset=utf-8"), out_type, out_size);
941++
942++ if (g_content_type_is_a (format, target_string))
943++ {
944++ *out_type = GDK_SELECTION_TYPE_STRING;
945++ *out_size = sizeof (guchar);
946++
947++ return 2;
948++ }
949++
950++ if (g_content_type_is_a (target_string, format))
951++ {
952++ *out_type = GDK_SELECTION_TYPE_STRING;
953++ *out_size = sizeof (guchar);
954++
955++ return 1;
956++ }
957++
958+ return 0;
959+ }
960+
961++static gint
962++get_best_format_index (const gchar * const *formats,
963++ guint n_formats,
964++ GdkAtom target,
965++ GdkAtom *out_type,
966++ gint *out_size)
967++{
968++ gint best_i = -1;
969++ gint best_score = 0;
970++ GdkAtom best_type;
971++ gint best_size;
972++ gint score;
973++ GdkAtom type;
974++ gint size;
975++ gint i;
976++
977++ if (!out_type)
978++ out_type = &best_type;
979++
980++ if (!out_size)
981++ out_size = &best_size;
982++
983++ *out_type = GDK_NONE;
984++ *out_size = 0;
985++
986++ for (i = 0; i < n_formats; i++)
987++ {
988++ score = get_format_score (formats[i], target, &type, &size);
989++
990++ if (score > best_score)
991++ {
992++ best_i = i;
993++ best_score = score;
994++ *out_type = type;
995++ *out_size = size;
996++ }
997++ }
998++
999++ return best_i;
1000++}
1001++
1002++static void
1003++gdk_mir_display_real_convert_selection (GdkDisplay *display,
1004++ GdkWindow *requestor,
1005++ GdkAtom selection,
1006++ GdkAtom target,
1007++ guint32 time)
1008++{
1009++ GdkMirDisplay *mir_display = GDK_MIR_DISPLAY (display);
1010++ const gchar *paste_data;
1011++ gsize paste_size;
1012++ const gint *paste_header;
1013++ GPtrArray *paste_formats;
1014++ GArray *paste_targets;
1015++ GdkAtom paste_target;
1016++ GdkEvent *event;
1017++ gint best_i;
1018++ GdkAtom best_type;
1019++ gint best_size;
1020++ gint i;
1021++
1022++ g_return_if_fail (mir_display->paste_data);
1023++
1024++ paste_data = g_variant_get_fixed_array (mir_display->paste_data, &paste_size, sizeof (guchar));
1025++ paste_header = (const gint *) paste_data;
1026++ paste_formats = g_ptr_array_new_full (paste_header[0], g_free);
1027++
1028++ for (i = 0; i < paste_header[0]; i++)
1029++ g_ptr_array_add (paste_formats, g_strndup (paste_data + paste_header[1 + 4 * i], paste_header[2 + 4 * i]));
1030++
1031++ if (target == gdk_atom_intern_static_string ("TARGETS"))
1032++ {
1033++ paste_targets = g_array_sized_new (TRUE, FALSE, sizeof (GdkAtom), paste_formats->len);
1034++
1035++ for (i = 0; i < paste_formats->len; i++)
1036++ {
1037++ paste_target = gdk_atom_intern (g_ptr_array_index (paste_formats, i), FALSE);
1038++ g_array_append_val (paste_targets, paste_target);
1039++ }
1040++
1041++ gdk_property_change (requestor,
1042++ gdk_atom_intern_static_string ("GDK_SELECTION"),
1043++ GDK_SELECTION_TYPE_ATOM,
1044++ 8 * sizeof (GdkAtom),
1045++ GDK_PROP_MODE_REPLACE,
1046++ (const guchar *) paste_targets->data,
1047++ paste_targets->len);
1048++
1049++ g_array_unref (paste_targets);
1050++
1051++ event = gdk_event_new (GDK_SELECTION_NOTIFY);
1052++ event->selection.window = g_object_ref (requestor);
1053++ event->selection.send_event = FALSE;
1054++ event->selection.selection = selection;
1055++ event->selection.target = target;
1056++ event->selection.property = gdk_atom_intern_static_string ("GDK_SELECTION");
1057++ event->selection.time = time;
1058++ event->selection.requestor = g_object_ref (requestor);
1059++
1060++ gdk_event_put (event);
1061++ gdk_event_free (event);
1062++ }
1063++ else
1064++ {
1065++ best_i = get_best_format_index ((const gchar * const *) paste_formats->pdata,
1066++ paste_formats->len,
1067++ target,
1068++ &best_type,
1069++ &best_size);
1070++
1071++ if (best_i >= 0)
1072++ {
1073++ gdk_property_change (requestor,
1074++ gdk_atom_intern_static_string ("GDK_SELECTION"),
1075++ best_type,
1076++ 8 * best_size,
1077++ GDK_PROP_MODE_REPLACE,
1078++ (const guchar *) paste_data + paste_header[3 + 4 * best_i],
1079++ paste_header[4 + 4 * best_i] / best_size);
1080++
1081++ event = gdk_event_new (GDK_SELECTION_NOTIFY);
1082++ event->selection.window = g_object_ref (requestor);
1083++ event->selection.send_event = FALSE;
1084++ event->selection.selection = selection;
1085++ event->selection.target = target;
1086++ event->selection.property = gdk_atom_intern_static_string ("GDK_SELECTION");
1087++ event->selection.time = time;
1088++ event->selection.requestor = g_object_ref (requestor);
1089++
1090++ gdk_event_put (event);
1091++ gdk_event_free (event);
1092++ }
1093++ }
1094++
1095++ g_ptr_array_unref (paste_formats);
1096++}
1097++
1098++typedef struct
1099++{
1100++ GdkDisplay *display;
1101++ GdkWindow *requestor;
1102++ GdkAtom selection;
1103++ GdkAtom target;
1104++ guint32 time;
1105++} ConvertInfo;
1106++
1107++static void
1108++paste_data_ready_cb (GObject *source_object,
1109++ GAsyncResult *res,
1110++ gpointer user_data)
1111++{
1112++ ContentHubService *content_service = CONTENT_HUB_SERVICE (source_object);
1113++ ConvertInfo *info = user_data;
1114++ GdkMirDisplay *mir_display = GDK_MIR_DISPLAY (info->display);
1115++ gboolean result;
1116++
1117++ g_clear_pointer (&mir_display->paste_data, g_variant_unref);
1118++
1119++ result = content_hub_service_call_get_latest_paste_data_finish (content_service,
1120++ &mir_display->paste_data,
1121++ res,
1122++ NULL);
1123++
1124++ if (result)
1125++ gdk_mir_display_real_convert_selection (info->display,
1126++ info->requestor,
1127++ info->selection,
1128++ info->target,
1129++ info->time);
1130++
1131++ g_object_unref (info->requestor);
1132++ g_object_unref (info->display);
1133++ g_free (info);
1134++}
1135++
1136+ static void
1137+ gdk_mir_display_convert_selection (GdkDisplay *display,
1138+ GdkWindow *requestor,
1139+@@ -558,7 +820,46 @@ gdk_mir_display_convert_selection (GdkDisplay *display,
1140+ GdkAtom target,
1141+ guint32 time)
1142+ {
1143+- //g_printerr ("gdk_mir_display_convert_selection\n");
1144++ GdkMirDisplay *mir_display = GDK_MIR_DISPLAY (display);
1145++ MirSurface *surface;
1146++ MirPersistentId *persistent_id;
1147++ ConvertInfo *info;
1148++
1149++ if (selection != GDK_SELECTION_CLIPBOARD)
1150++ return;
1151++ else if (mir_display->paste_data)
1152++ gdk_mir_display_real_convert_selection (display, requestor, selection, target, time);
1153++ else if (mir_display->focused_window)
1154++ {
1155++ surface = gdk_mir_window_get_mir_surface (mir_display->focused_window);
1156++
1157++ if (!surface)
1158++ return;
1159++
1160++ persistent_id = mir_surface_request_persistent_id_sync (surface);
1161++
1162++ if (!persistent_id)
1163++ return;
1164++
1165++ if (mir_persistent_id_is_valid (persistent_id))
1166++ {
1167++ info = g_new (ConvertInfo, 1);
1168++ info->display = g_object_ref (display);
1169++ info->requestor = g_object_ref (requestor);
1170++ info->selection = selection;
1171++ info->target = target;
1172++ info->time = time;
1173++
1174++ content_hub_service_call_get_latest_paste_data (
1175++ mir_display->content_service,
1176++ mir_persistent_id_as_string (persistent_id),
1177++ NULL,
1178++ paste_data_ready_cb,
1179++ info);
1180++ }
1181++
1182++ mir_persistent_id_release (persistent_id);
1183++ }
1184+ }
1185+
1186+ static gint
1187+@@ -569,8 +870,38 @@ gdk_mir_display_text_property_to_utf8_list (GdkDisplay *display,
1188+ gint length,
1189+ gchar ***list)
1190+ {
1191+- //g_printerr ("gdk_mir_display_text_property_to_utf8_list\n");
1192+- return 0;
1193++ GPtrArray *array;
1194++ const gchar *ptr;
1195++ gsize chunk_len;
1196++ gchar *copy;
1197++ guint nitems;
1198++
1199++ ptr = (const gchar *) text;
1200++ array = g_ptr_array_new ();
1201++
1202++ /* split text into utf-8 strings */
1203++ while (ptr < (const gchar *) &text[length])
1204++ {
1205++ chunk_len = strlen (ptr);
1206++
1207++ if (g_utf8_validate (ptr, chunk_len, NULL))
1208++ {
1209++ copy = g_strndup (ptr, chunk_len);
1210++ g_ptr_array_add (array, copy);
1211++ }
1212++
1213++ ptr = &ptr[chunk_len + 1];
1214++ }
1215++
1216++ nitems = array->len;
1217++ g_ptr_array_add (array, NULL);
1218++
1219++ if (list)
1220++ *list = (gchar **) g_ptr_array_free (array, FALSE);
1221++ else
1222++ g_ptr_array_free (array, TRUE);
1223++
1224++ return nitems;
1225+ }
1226+
1227+ static gchar *
1228+--
1229+2.10.2
1230+
1231
1232=== added file 'debian/patches/0006-mir-properly-handle-empty-clipboard.patch'
1233--- debian/patches/0006-mir-properly-handle-empty-clipboard.patch 1970-01-01 00:00:00 +0000
1234+++ debian/patches/0006-mir-properly-handle-empty-clipboard.patch 2017-02-08 17:37:49 +0000
1235@@ -0,0 +1,37 @@
1236+From 248ef2d6a0f97cbb71d10c0bb37a3183f13ea19f Mon Sep 17 00:00:00 2001
1237+From: William Hua <william.hua@canonical.com>
1238+Date: Mon, 9 Jan 2017 12:04:48 -0500
1239+Subject: [PATCH 06/38] mir: properly handle empty clipboard
1240+
1241+https://bugzilla.gnome.org/show_bug.cgi?id=775732
1242+---
1243+ gdk/mir/gdkmirdisplay.c | 12 +++++++++---
1244+ 1 file changed, 9 insertions(+), 3 deletions(-)
1245+
1246+diff --git a/gdk/mir/gdkmirdisplay.c b/gdk/mir/gdkmirdisplay.c
1247+index 21967ac..62f36ee 100644
1248+--- a/gdk/mir/gdkmirdisplay.c
1249++++ b/gdk/mir/gdkmirdisplay.c
1250+@@ -703,10 +703,16 @@ gdk_mir_display_real_convert_selection (GdkDisplay *display,
1251+
1252+ paste_data = g_variant_get_fixed_array (mir_display->paste_data, &paste_size, sizeof (guchar));
1253+ paste_header = (const gint *) paste_data;
1254+- paste_formats = g_ptr_array_new_full (paste_header[0], g_free);
1255+
1256+- for (i = 0; i < paste_header[0]; i++)
1257+- g_ptr_array_add (paste_formats, g_strndup (paste_data + paste_header[1 + 4 * i], paste_header[2 + 4 * i]));
1258++ if (paste_data)
1259++ {
1260++ paste_formats = g_ptr_array_new_full (paste_header[0], g_free);
1261++
1262++ for (i = 0; i < paste_header[0]; i++)
1263++ g_ptr_array_add (paste_formats, g_strndup (paste_data + paste_header[1 + 4 * i], paste_header[2 + 4 * i]));
1264++ }
1265++ else
1266++ paste_formats = g_ptr_array_new_with_free_func (g_free);
1267+
1268+ if (target == gdk_atom_intern_static_string ("TARGETS"))
1269+ {
1270+--
1271+2.10.2
1272+
1273
1274=== added file 'debian/patches/0031-mir-fix-compile-time-warnings.patch'
1275--- debian/patches/0031-mir-fix-compile-time-warnings.patch 1970-01-01 00:00:00 +0000
1276+++ debian/patches/0031-mir-fix-compile-time-warnings.patch 2017-02-08 17:37:49 +0000
1277@@ -0,0 +1,77 @@
1278+From a95feb498409b42d7b7dd08b2c89c98b70b0a9fe Mon Sep 17 00:00:00 2001
1279+From: William Hua <william.hua@canonical.com>
1280+Date: Mon, 9 Jan 2017 17:54:37 -0500
1281+Subject: [PATCH 31/38] mir: fix compile-time warnings
1282+
1283+---
1284+ gdk/mir/gdkmir-debug.c | 10 ++++++++++
1285+ gdk/mir/gdkmireventsource.c | 2 ++
1286+ gdk/mir/gdkmirscreen.c | 4 ++++
1287+ 3 files changed, 16 insertions(+)
1288+
1289+diff --git a/gdk/mir/gdkmir-debug.c b/gdk/mir/gdkmir-debug.c
1290+index 7dd54d5..b0ff929 100644
1291+--- a/gdk/mir/gdkmir-debug.c
1292++++ b/gdk/mir/gdkmir-debug.c
1293+@@ -127,6 +127,7 @@ _gdk_mir_print_touch_event (const MirInputEvent *event)
1294+ }
1295+ switch (mir_touch_event_tooltype (touch_event, i))
1296+ {
1297++ default:
1298+ case mir_touch_tooltype_unknown:
1299+ g_printerr (" ? ");
1300+ break;
1301+@@ -200,6 +201,12 @@ _gdk_mir_print_motion_event (const MirInputEvent *event)
1302+ }
1303+
1304+ static void
1305++_gdk_mir_print_input_event (const MirInputEvent *event)
1306++{
1307++ g_printerr ("INPUT\n");
1308++}
1309++
1310++static void
1311+ _gdk_mir_print_surface_event (const MirSurfaceEvent *event)
1312+ {
1313+ g_printerr ("SURFACE\n");
1314+@@ -260,6 +267,9 @@ _gdk_mir_print_event (const MirEvent *event)
1315+ case mir_input_event_type_pointer:
1316+ _gdk_mir_print_motion_event (mir_event_get_input_event (event));
1317+ break;
1318++ default:
1319++ _gdk_mir_print_input_event (mir_event_get_input_event (event));
1320++ break;
1321+ }
1322+ break;
1323+ case mir_event_type_key:
1324+diff --git a/gdk/mir/gdkmireventsource.c b/gdk/mir/gdkmireventsource.c
1325+index a2a1a12..d3c85b9 100644
1326+--- a/gdk/mir/gdkmireventsource.c
1327++++ b/gdk/mir/gdkmireventsource.c
1328+@@ -571,6 +571,8 @@ gdk_mir_event_source_queue_event (GdkDisplay *display,
1329+ case mir_input_event_type_pointer:
1330+ handle_motion_event (window, input_event);
1331+ break;
1332++ default:
1333++ break;
1334+ }
1335+
1336+ break;
1337+diff --git a/gdk/mir/gdkmirscreen.c b/gdk/mir/gdkmirscreen.c
1338+index b369b03..979f2ba 100644
1339+--- a/gdk/mir/gdkmirscreen.c
1340++++ b/gdk/mir/gdkmirscreen.c
1341+@@ -354,6 +354,10 @@ gdk_mir_screen_get_monitor_plug_name (GdkScreen *screen,
1342+ return g_strdup_printf ("eDP-%u", output->output_id);
1343+ case mir_display_output_type_virtual:
1344+ return g_strdup_printf ("Virtual-%u", output->output_id);
1345++ case mir_display_output_type_dsi:
1346++ return g_strdup_printf ("DSI-%u", output->output_id);
1347++ case mir_display_output_type_dpi:
1348++ return g_strdup_printf ("DPI-%u", output->output_id);
1349+ }
1350+ }
1351+
1352+--
1353+2.10.2
1354+
1355
1356=== added file 'debian/patches/0032-mir-use-modal-window-hint.patch'
1357--- debian/patches/0032-mir-use-modal-window-hint.patch 1970-01-01 00:00:00 +0000
1358+++ debian/patches/0032-mir-use-modal-window-hint.patch 2017-02-08 17:37:49 +0000
1359@@ -0,0 +1,76 @@
1360+From 5d7db3246e503016462fa28d34b1b3eafe4754d0 Mon Sep 17 00:00:00 2001
1361+From: William Hua <william.hua@canonical.com>
1362+Date: Thu, 12 Jan 2017 17:16:27 -0500
1363+Subject: [PATCH 32/38] mir: use modal window hint
1364+
1365+---
1366+ gdk/mir/gdkmirwindowimpl.c | 25 +++++++++++++++++++++++--
1367+ 1 file changed, 23 insertions(+), 2 deletions(-)
1368+
1369+diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
1370+index 8a15816..1f48dfb 100644
1371+--- a/gdk/mir/gdkmirwindowimpl.c
1372++++ b/gdk/mir/gdkmirwindowimpl.c
1373+@@ -88,6 +88,7 @@ struct _GdkMirWindowImpl
1374+ /* Desired surface attributes */
1375+ GdkWindowTypeHint type_hint;
1376+ MirSurfaceState surface_state;
1377++ gboolean modal;
1378+
1379+ /* Pattern for background */
1380+ cairo_pattern_t *background;
1381+@@ -305,6 +306,7 @@ create_window_type_spec (GdkDisplay *display,
1382+ gint y,
1383+ gint width,
1384+ gint height,
1385++ gboolean modal,
1386+ GdkWindowTypeHint type,
1387+ const MirRectangle *rect,
1388+ MirEdgeAttachment edge,
1389+@@ -358,6 +360,17 @@ create_window_type_spec (GdkDisplay *display,
1390+ switch (type)
1391+ {
1392+ case GDK_WINDOW_TYPE_HINT_DIALOG:
1393++ if (modal)
1394++ return mir_connection_create_spec_for_modal_dialog (connection,
1395++ width,
1396++ height,
1397++ format,
1398++ parent_surface);
1399++ else
1400++ return mir_connection_create_spec_for_dialog (connection,
1401++ width,
1402++ height,
1403++ format);
1404+ case GDK_WINDOW_TYPE_HINT_DOCK:
1405+ return mir_connection_create_spec_for_dialog (connection,
1406+ width,
1407+@@ -430,6 +443,7 @@ create_spec (GdkWindow *window, GdkMirWindowImpl *impl)
1408+ impl->transient_for,
1409+ impl->transient_x, impl->transient_y,
1410+ window->width, window->height,
1411++ impl->modal,
1412+ impl->type_hint,
1413+ impl->has_rect ? &impl->rect : NULL,
1414+ impl->has_rect ? impl->edge : mir_edge_attachment_any,
1415+@@ -1133,8 +1147,15 @@ void
1416+ gdk_mir_window_impl_set_modal_hint (GdkWindow *window,
1417+ gboolean modal)
1418+ {
1419+- //g_printerr ("gdk_mir_window_impl_set_modal_hint window=%p\n", window);
1420+- /* Mir doesn't support modal windows */
1421++ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
1422++
1423++ if (modal != impl->modal)
1424++ {
1425++ impl->modal = modal;
1426++
1427++ if (impl->surface && !impl->pending_spec_update)
1428++ update_surface_spec (window);
1429++ }
1430+ }
1431+
1432+ static void
1433+--
1434+2.10.2
1435+
1436
1437=== added file 'debian/patches/0036-mir-use-mir_surface_spec_set_placement-for-menus.patch'
1438--- debian/patches/0036-mir-use-mir_surface_spec_set_placement-for-menus.patch 1970-01-01 00:00:00 +0000
1439+++ debian/patches/0036-mir-use-mir_surface_spec_set_placement-for-menus.patch 2017-02-08 17:37:49 +0000
1440@@ -0,0 +1,334 @@
1441+From 14c8e25cb2063ff3a91b59328b7f45bcbc4cd875 Mon Sep 17 00:00:00 2001
1442+From: William Hua <william.hua@canonical.com>
1443+Date: Fri, 27 Jan 2017 14:46:10 -0500
1444+Subject: [PATCH 36/38] mir: use mir_surface_spec_set_placement for menus
1445+
1446+This API was added to Mir for GTK menus, combo boxes, etc.
1447+---
1448+ gdk/mir/gdkmirwindowimpl.c | 240 ++++++++++++++++++++++++++++++---------------
1449+ 1 file changed, 159 insertions(+), 81 deletions(-)
1450+
1451+diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
1452+index 1f48dfb..6fe0b3c 100644
1453+--- a/gdk/mir/gdkmirwindowimpl.c
1454++++ b/gdk/mir/gdkmirwindowimpl.c
1455+@@ -80,10 +80,15 @@ struct _GdkMirWindowImpl
1456+ gint transient_x;
1457+ gint transient_y;
1458+
1459+- /* Anchor rectangle */
1460+- gboolean has_rect;
1461+- MirRectangle rect;
1462+- MirEdgeAttachment edge;
1463++ /* gdk_window_move_to_rect */
1464++ gboolean has_rect;
1465++ GdkRectangle rect;
1466++ MirRectangle mir_rect;
1467++ MirPlacementGravity rect_anchor;
1468++ MirPlacementGravity window_anchor;
1469++ MirPlacementHints anchor_hints;
1470++ gint rect_anchor_dx;
1471++ gint rect_anchor_dy;
1472+
1473+ /* Desired surface attributes */
1474+ GdkWindowTypeHint type_hint;
1475+@@ -308,16 +313,12 @@ create_window_type_spec (GdkDisplay *display,
1476+ gint height,
1477+ gboolean modal,
1478+ GdkWindowTypeHint type,
1479+- const MirRectangle *rect,
1480+- MirEdgeAttachment edge,
1481+ MirBufferUsage buffer_usage)
1482+ {
1483+- MirPixelFormat format;
1484+- MirSurface *parent_surface = NULL;
1485+ MirConnection *connection = gdk_mir_display_get_mir_connection (display);
1486+- MirRectangle real_rect;
1487+-
1488+- format = _gdk_mir_display_get_pixel_format (display, buffer_usage);
1489++ MirSurface *parent_surface = NULL;
1490++ MirPixelFormat format;
1491++ MirRectangle rect;
1492+
1493+ if (parent && parent->impl)
1494+ {
1495+@@ -338,24 +339,12 @@ create_window_type_spec (GdkDisplay *display,
1496+ }
1497+ }
1498+
1499+- if (rect)
1500+- {
1501+- real_rect = *rect;
1502++ format = _gdk_mir_display_get_pixel_format (display, buffer_usage);
1503+
1504+- while (parent && !gdk_window_has_native (parent) && gdk_window_get_effective_parent (parent))
1505+- {
1506+- real_rect.left += parent->x;
1507+- real_rect.top += parent->y;
1508+- parent = gdk_window_get_effective_parent (parent);
1509+- }
1510+- }
1511+- else
1512+- {
1513+- real_rect.left = x;
1514+- real_rect.top = y;
1515+- real_rect.width = 1;
1516+- real_rect.height = 1;
1517+- }
1518++ rect.left = x;
1519++ rect.top = y;
1520++ rect.width = 1;
1521++ rect.height = 1;
1522+
1523+ switch (type)
1524+ {
1525+@@ -389,9 +378,8 @@ create_window_type_spec (GdkDisplay *display,
1526+ height,
1527+ format,
1528+ parent_surface,
1529+- &real_rect,
1530+- edge);
1531+- break;
1532++ &rect,
1533++ 0);
1534+ case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
1535+ case GDK_WINDOW_TYPE_HINT_UTILITY:
1536+ return mir_connection_create_spec_for_modal_dialog (connection,
1537+@@ -438,15 +426,16 @@ static MirSurfaceSpec*
1538+ create_spec (GdkWindow *window, GdkMirWindowImpl *impl)
1539+ {
1540+ MirSurfaceSpec *spec = NULL;
1541++ GdkWindow *parent;
1542+
1543+ spec = create_window_type_spec (impl->display,
1544+ impl->transient_for,
1545+- impl->transient_x, impl->transient_y,
1546+- window->width, window->height,
1547++ impl->transient_x,
1548++ impl->transient_y,
1549++ window->width,
1550++ window->height,
1551+ impl->modal,
1552+ impl->type_hint,
1553+- impl->has_rect ? &impl->rect : NULL,
1554+- impl->has_rect ? impl->edge : mir_edge_attachment_any,
1555+ impl->buffer_usage);
1556+
1557+ mir_surface_spec_set_name (spec, impl->title);
1558+@@ -454,6 +443,32 @@ create_spec (GdkWindow *window, GdkMirWindowImpl *impl)
1559+
1560+ apply_geometry_hints (spec, impl);
1561+
1562++ if (impl->has_rect)
1563++ {
1564++ impl->mir_rect.left = impl->rect.x;
1565++ impl->mir_rect.top = impl->rect.y;
1566++ impl->mir_rect.width = impl->rect.width;
1567++ impl->mir_rect.height = impl->rect.height;
1568++
1569++ parent = impl->transient_for;
1570++
1571++ while (parent && !gdk_window_has_native (parent))
1572++ {
1573++ impl->mir_rect.left += parent->x;
1574++ impl->mir_rect.top += parent->y;
1575++
1576++ parent = gdk_window_get_parent (parent);
1577++ }
1578++
1579++ mir_surface_spec_set_placement (spec,
1580++ &impl->mir_rect,
1581++ impl->rect_anchor,
1582++ impl->window_anchor,
1583++ impl->anchor_hints,
1584++ impl->rect_anchor_dx,
1585++ impl->rect_anchor_dy);
1586++ }
1587++
1588+ return spec;
1589+ }
1590+
1591+@@ -861,52 +876,117 @@ gdk_mir_window_impl_move_resize (GdkWindow *window,
1592+ }
1593+ }
1594+
1595+-static MirEdgeAttachment
1596+-get_edge_for_anchors (GdkGravity rect_anchor,
1597+- GdkGravity window_anchor,
1598+- GdkAnchorHints anchor_hints)
1599++static MirPlacementGravity
1600++get_mir_placement_gravity (GdkGravity gravity)
1601+ {
1602+- MirEdgeAttachment edge = 0;
1603++ switch (gravity)
1604++ {
1605++ case GDK_GRAVITY_STATIC:
1606++ case GDK_GRAVITY_NORTH_WEST:
1607++ return mir_placement_gravity_northwest;
1608++ case GDK_GRAVITY_NORTH:
1609++ return mir_placement_gravity_north;
1610++ case GDK_GRAVITY_NORTH_EAST:
1611++ return mir_placement_gravity_northeast;
1612++ case GDK_GRAVITY_WEST:
1613++ return mir_placement_gravity_west;
1614++ case GDK_GRAVITY_CENTER:
1615++ return mir_placement_gravity_center;
1616++ case GDK_GRAVITY_EAST:
1617++ return mir_placement_gravity_east;
1618++ case GDK_GRAVITY_SOUTH_WEST:
1619++ return mir_placement_gravity_southwest;
1620++ case GDK_GRAVITY_SOUTH:
1621++ return mir_placement_gravity_south;
1622++ case GDK_GRAVITY_SOUTH_EAST:
1623++ return mir_placement_gravity_southeast;
1624++ }
1625+
1626+- if (anchor_hints & GDK_ANCHOR_FLIP_X)
1627+- edge |= mir_edge_attachment_vertical;
1628++ g_warn_if_reached ();
1629+
1630+- if (anchor_hints & GDK_ANCHOR_FLIP_Y)
1631+- edge |= mir_edge_attachment_horizontal;
1632++ return mir_placement_gravity_center;
1633++}
1634++
1635++static MirPlacementHints
1636++get_mir_placement_hints (GdkAnchorHints hints)
1637++{
1638++ MirPlacementHints mir_hints = 0;
1639++
1640++ if (hints & GDK_ANCHOR_FLIP_X)
1641++ mir_hints |= mir_placement_hints_flip_x;
1642++
1643++ if (hints & GDK_ANCHOR_FLIP_Y)
1644++ mir_hints |= mir_placement_hints_flip_y;
1645++
1646++ if (hints & GDK_ANCHOR_SLIDE_X)
1647++ mir_hints |= mir_placement_hints_slide_x;
1648++
1649++ if (hints & GDK_ANCHOR_SLIDE_Y)
1650++ mir_hints |= mir_placement_hints_slide_y;
1651+
1652+- return edge;
1653++ if (hints & GDK_ANCHOR_RESIZE_X)
1654++ mir_hints |= mir_placement_hints_resize_x;
1655++
1656++ if (hints & GDK_ANCHOR_RESIZE_Y)
1657++ mir_hints |= mir_placement_hints_resize_y;
1658++
1659++ return mir_hints;
1660+ }
1661+
1662+-static void
1663+-get_rect_for_edge (MirRectangle *out_rect,
1664+- const GdkRectangle *in_rect,
1665+- MirEdgeAttachment edge,
1666+- GdkWindow *window)
1667++static gint
1668++get_window_shadow_dx (GdkWindow *window,
1669++ GdkGravity window_anchor)
1670+ {
1671+- out_rect->left = in_rect->x;
1672+- out_rect->top = in_rect->y;
1673+- out_rect->width = in_rect->width;
1674+- out_rect->height = in_rect->height;
1675++ switch (window_anchor)
1676++ {
1677++ case GDK_GRAVITY_STATIC:
1678++ case GDK_GRAVITY_NORTH_WEST:
1679++ case GDK_GRAVITY_WEST:
1680++ case GDK_GRAVITY_SOUTH_WEST:
1681++ return -window->shadow_left;
1682++
1683++ case GDK_GRAVITY_NORTH:
1684++ case GDK_GRAVITY_CENTER:
1685++ case GDK_GRAVITY_SOUTH:
1686++ return (window->shadow_right - window->shadow_left) / 2;
1687++
1688++ case GDK_GRAVITY_NORTH_EAST:
1689++ case GDK_GRAVITY_EAST:
1690++ case GDK_GRAVITY_SOUTH_EAST:
1691++ return window->shadow_right;
1692++ }
1693+
1694+- switch (edge)
1695++ g_warn_if_reached ();
1696++
1697++ return 0;
1698++}
1699++
1700++static gint
1701++get_window_shadow_dy (GdkWindow *window,
1702++ GdkGravity window_anchor)
1703++{
1704++ switch (window_anchor)
1705+ {
1706+- case mir_edge_attachment_vertical:
1707+- out_rect->left += window->shadow_right;
1708+- out_rect->top -= window->shadow_top;
1709+- out_rect->width -= window->shadow_left + window->shadow_right;
1710+- out_rect->height += window->shadow_top + window->shadow_bottom;
1711+- break;
1712+-
1713+- case mir_edge_attachment_horizontal:
1714+- out_rect->left -= window->shadow_left;
1715+- out_rect->top += window->shadow_bottom;
1716+- out_rect->width += window->shadow_left + window->shadow_right;
1717+- out_rect->height -= window->shadow_top + window->shadow_bottom;
1718+- break;
1719+-
1720+- default:
1721+- break;
1722++ case GDK_GRAVITY_STATIC:
1723++ case GDK_GRAVITY_NORTH_WEST:
1724++ case GDK_GRAVITY_NORTH:
1725++ case GDK_GRAVITY_NORTH_EAST:
1726++ return -window->shadow_top;
1727++
1728++ case GDK_GRAVITY_WEST:
1729++ case GDK_GRAVITY_CENTER:
1730++ case GDK_GRAVITY_EAST:
1731++ return (window->shadow_bottom - window->shadow_top) / 2;
1732++
1733++ case GDK_GRAVITY_SOUTH_WEST:
1734++ case GDK_GRAVITY_SOUTH:
1735++ case GDK_GRAVITY_SOUTH_EAST:
1736++ return window->shadow_bottom;
1737+ }
1738++
1739++ g_warn_if_reached ();
1740++
1741++ return 0;
1742+ }
1743+
1744+ static void
1745+@@ -920,18 +1000,16 @@ gdk_mir_window_impl_move_to_rect (GdkWindow *window,
1746+ {
1747+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
1748+
1749+- impl->edge = get_edge_for_anchors (rect_anchor, window_anchor, anchor_hints);
1750+- get_rect_for_edge (&impl->rect, rect, impl->edge, window);
1751+ impl->has_rect = TRUE;
1752++ impl->rect = *rect;
1753++ impl->rect_anchor = get_mir_placement_gravity (rect_anchor);
1754++ impl->window_anchor = get_mir_placement_gravity (window_anchor);
1755++ impl->anchor_hints = get_mir_placement_hints (anchor_hints);
1756++ impl->rect_anchor_dx = rect_anchor_dx + get_window_shadow_dx (window, window_anchor);
1757++ impl->rect_anchor_dy = rect_anchor_dy + get_window_shadow_dy (window, window_anchor);
1758+
1759+- ensure_no_surface (window);
1760+-
1761+- g_signal_emit_by_name (window,
1762+- "moved-to-rect",
1763+- NULL,
1764+- NULL,
1765+- FALSE,
1766+- FALSE);
1767++ if (impl->surface && !impl->pending_spec_update)
1768++ update_surface_spec (window);
1769+ }
1770+
1771+ static void
1772+--
1773+2.10.2
1774+
1775
1776=== added file 'debian/patches/0037-mir-handle-surface-placement-events.patch'
1777--- debian/patches/0037-mir-handle-surface-placement-events.patch 1970-01-01 00:00:00 +0000
1778+++ debian/patches/0037-mir-handle-surface-placement-events.patch 2017-02-08 17:37:49 +0000
1779@@ -0,0 +1,287 @@
1780+From d9947b671a2c605ef64cb720d2a9c6c80b39e7af Mon Sep 17 00:00:00 2001
1781+From: William Hua <william.hua@canonical.com>
1782+Date: Sun, 29 Jan 2017 11:24:43 -0500
1783+Subject: [PATCH 37/38] mir: handle surface placement events
1784+
1785+This allows the Mir backend to properly emit "moved-to-rect."
1786+---
1787+ gdk/mir/gdkmir-private.h | 2 +
1788+ gdk/mir/gdkmir.h | 1 +
1789+ gdk/mir/gdkmireventsource.c | 10 +++
1790+ gdk/mir/gdkmirwindowimpl.c | 207 ++++++++++++++++++++++++++++++++++++++++++++
1791+ 4 files changed, 220 insertions(+)
1792+
1793+diff --git a/gdk/mir/gdkmir-private.h b/gdk/mir/gdkmir-private.h
1794+index a677dec..4595dc5 100644
1795+--- a/gdk/mir/gdkmir-private.h
1796++++ b/gdk/mir/gdkmir-private.h
1797+@@ -91,6 +91,8 @@ void _gdk_mir_window_impl_set_surface_type (GdkMirWindowImpl *impl, MirSurfaceTy
1798+
1799+ void _gdk_mir_window_set_surface_output (GdkWindow *window, gdouble scale);
1800+
1801++void _gdk_mir_window_set_final_rect (GdkWindow *window, MirRectangle rect);
1802++
1803+ void _gdk_mir_window_impl_set_cursor_state (GdkMirWindowImpl *impl, gdouble x, gdouble y, gboolean cursor_inside, guint button_state);
1804+
1805+ void _gdk_mir_window_impl_get_cursor_state (GdkMirWindowImpl *impl, gdouble *x, gdouble *y, gboolean *cursor_inside, guint *button_state);
1806+diff --git a/gdk/mir/gdkmir.h b/gdk/mir/gdkmir.h
1807+index 38cc80c..6e92fcf 100644
1808+--- a/gdk/mir/gdkmir.h
1809++++ b/gdk/mir/gdkmir.h
1810+@@ -20,6 +20,7 @@
1811+
1812+ #include <gdk/gdk.h>
1813+ #include <mir_toolkit/mir_client_library.h>
1814++#include <mir_toolkit/events/surface_placement.h>
1815+
1816+ G_BEGIN_DECLS
1817+
1818+diff --git a/gdk/mir/gdkmireventsource.c b/gdk/mir/gdkmireventsource.c
1819+index d3c85b9..3ebf156 100644
1820+--- a/gdk/mir/gdkmireventsource.c
1821++++ b/gdk/mir/gdkmireventsource.c
1822+@@ -541,6 +541,13 @@ handle_surface_output_event (GdkWindow *window,
1823+ _gdk_mir_window_set_surface_output (window, mir_surface_output_event_get_scale (event));
1824+ }
1825+
1826++static void
1827++handle_surface_placement_event (GdkWindow *window,
1828++ const MirSurfacePlacementEvent *event)
1829++{
1830++ _gdk_mir_window_set_final_rect (window, mir_surface_placement_get_relative_position (event));
1831++}
1832++
1833+ typedef struct
1834+ {
1835+ GdkWindow *window;
1836+@@ -600,6 +607,9 @@ gdk_mir_event_source_queue_event (GdkDisplay *display,
1837+ case mir_event_type_surface_output:
1838+ handle_surface_output_event (window, mir_event_get_surface_output_event (event));
1839+ break;
1840++ case mir_event_type_surface_placement:
1841++ handle_surface_placement_event (window, mir_event_get_surface_placement_event (event));
1842++ break;
1843+ default:
1844+ g_warning ("Ignoring unknown Mir event %d", mir_event_get_type (event));
1845+ // FIXME?
1846+diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
1847+index 6fe0b3c..1b016ec 100644
1848+--- a/gdk/mir/gdkmirwindowimpl.c
1849++++ b/gdk/mir/gdkmirwindowimpl.c
1850+@@ -1012,6 +1012,213 @@ gdk_mir_window_impl_move_to_rect (GdkWindow *window,
1851+ update_surface_spec (window);
1852+ }
1853+
1854++static gint
1855++get_mir_placement_gravity_x (MirPlacementGravity gravity)
1856++{
1857++ switch (gravity)
1858++ {
1859++ case mir_placement_gravity_west:
1860++ case mir_placement_gravity_northwest:
1861++ case mir_placement_gravity_southwest:
1862++ return 0;
1863++
1864++ case mir_placement_gravity_center:
1865++ case mir_placement_gravity_north:
1866++ case mir_placement_gravity_south:
1867++ return 1;
1868++
1869++ case mir_placement_gravity_east:
1870++ case mir_placement_gravity_northeast:
1871++ case mir_placement_gravity_southeast:
1872++ return 2;
1873++ }
1874++
1875++ g_warn_if_reached ();
1876++
1877++ return 1;
1878++}
1879++
1880++static gint
1881++get_mir_placement_gravity_y (MirPlacementGravity gravity)
1882++{
1883++ switch (gravity)
1884++ {
1885++ case mir_placement_gravity_north:
1886++ case mir_placement_gravity_northwest:
1887++ case mir_placement_gravity_northeast:
1888++ return 0;
1889++
1890++ case mir_placement_gravity_center:
1891++ case mir_placement_gravity_west:
1892++ case mir_placement_gravity_east:
1893++ return 1;
1894++
1895++ case mir_placement_gravity_south:
1896++ case mir_placement_gravity_southwest:
1897++ case mir_placement_gravity_southeast:
1898++ return 2;
1899++ }
1900++
1901++ g_warn_if_reached ();
1902++
1903++ return 1;
1904++}
1905++
1906++static GdkRectangle
1907++get_unflipped_rect (const GdkRectangle *rect,
1908++ gint width,
1909++ gint height,
1910++ MirPlacementGravity rect_anchor,
1911++ MirPlacementGravity window_anchor,
1912++ gint rect_anchor_dx,
1913++ gint rect_anchor_dy)
1914++{
1915++ GdkRectangle unflipped_rect;
1916++
1917++ unflipped_rect.x = rect->x;
1918++ unflipped_rect.x += rect->width * get_mir_placement_gravity_x (rect_anchor) / 2;
1919++ unflipped_rect.x -= width * get_mir_placement_gravity_x (window_anchor) / 2;
1920++ unflipped_rect.x += rect_anchor_dx;
1921++ unflipped_rect.y = rect->y;
1922++ unflipped_rect.y += rect->height * get_mir_placement_gravity_y (rect_anchor) / 2;
1923++ unflipped_rect.y -= height * get_mir_placement_gravity_y (window_anchor) / 2;
1924++ unflipped_rect.y += rect_anchor_dy;
1925++ unflipped_rect.width = width;
1926++ unflipped_rect.height = height;
1927++
1928++ return unflipped_rect;
1929++}
1930++
1931++static MirPlacementGravity
1932++get_opposite_mir_placement_gravity (MirPlacementGravity gravity)
1933++{
1934++ switch (gravity)
1935++ {
1936++ case mir_placement_gravity_center:
1937++ return mir_placement_gravity_center;
1938++ case mir_placement_gravity_west:
1939++ return mir_placement_gravity_east;
1940++ case mir_placement_gravity_east:
1941++ return mir_placement_gravity_west;
1942++ case mir_placement_gravity_north:
1943++ return mir_placement_gravity_south;
1944++ case mir_placement_gravity_south:
1945++ return mir_placement_gravity_north;
1946++ case mir_placement_gravity_northwest:
1947++ return mir_placement_gravity_southeast;
1948++ case mir_placement_gravity_northeast:
1949++ return mir_placement_gravity_southwest;
1950++ case mir_placement_gravity_southwest:
1951++ return mir_placement_gravity_northeast;
1952++ case mir_placement_gravity_southeast:
1953++ return mir_placement_gravity_northwest;
1954++ }
1955++
1956++ g_warn_if_reached ();
1957++
1958++ return gravity;
1959++}
1960++
1961++static gint
1962++get_anchor_x (const GdkRectangle *rect,
1963++ MirPlacementGravity anchor)
1964++{
1965++ return rect->x + rect->width * get_mir_placement_gravity_x (anchor) / 2;
1966++}
1967++
1968++static gint
1969++get_anchor_y (const GdkRectangle *rect,
1970++ MirPlacementGravity anchor)
1971++{
1972++ return rect->y + rect->height * get_mir_placement_gravity_y (anchor) / 2;
1973++}
1974++
1975++void
1976++_gdk_mir_window_set_final_rect (GdkWindow *window,
1977++ MirRectangle rect)
1978++{
1979++ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
1980++ GdkRectangle best_rect;
1981++ GdkRectangle worst_rect;
1982++ GdkRectangle flipped_rect;
1983++ GdkRectangle final_rect;
1984++ gboolean flipped_x = FALSE;
1985++ gboolean flipped_y = FALSE;
1986++ gint test_position;
1987++ gint final_position;
1988++ gint unflipped_offset;
1989++ gint flipped_offset;
1990++
1991++ g_return_if_fail (impl->has_rect);
1992++
1993++ best_rect = get_unflipped_rect (&impl->rect,
1994++ window->width,
1995++ window->height,
1996++ impl->rect_anchor,
1997++ impl->window_anchor,
1998++ impl->rect_anchor_dx,
1999++ impl->rect_anchor_dy);
2000++
2001++ worst_rect = get_unflipped_rect (&impl->rect,
2002++ window->width,
2003++ window->height,
2004++ get_opposite_mir_placement_gravity (impl->rect_anchor),
2005++ get_opposite_mir_placement_gravity (impl->window_anchor),
2006++ -impl->rect_anchor_dx,
2007++ -impl->rect_anchor_dy);
2008++
2009++ flipped_rect.x = best_rect.x;
2010++ flipped_rect.y = best_rect.y;
2011++ flipped_rect.width = window->width;
2012++ flipped_rect.height = window->height;
2013++
2014++ final_rect.x = rect.left - (impl->mir_rect.left - impl->rect.x);
2015++ final_rect.y = rect.top - (impl->mir_rect.top - impl->rect.y);
2016++ final_rect.width = rect.width;
2017++ final_rect.height = rect.height;
2018++
2019++ if (impl->anchor_hints & mir_placement_hints_flip_x)
2020++ {
2021++ test_position = get_anchor_x (&best_rect, impl->window_anchor);
2022++ final_position = get_anchor_x (&final_rect, impl->window_anchor);
2023++ unflipped_offset = final_position - test_position;
2024++
2025++ test_position = get_anchor_x (&worst_rect, get_opposite_mir_placement_gravity (impl->window_anchor));
2026++ final_position = get_anchor_x (&final_rect, get_opposite_mir_placement_gravity (impl->window_anchor));
2027++ flipped_offset = final_position - test_position;
2028++
2029++ if (ABS (flipped_offset) < ABS (unflipped_offset))
2030++ {
2031++ flipped_rect.x = worst_rect.x;
2032++ flipped_x = TRUE;
2033++ }
2034++ }
2035++
2036++ if (impl->anchor_hints & mir_placement_hints_flip_y)
2037++ {
2038++ test_position = get_anchor_y (&best_rect, impl->window_anchor);
2039++ final_position = get_anchor_y (&final_rect, impl->window_anchor);
2040++ unflipped_offset = final_position - test_position;
2041++
2042++ test_position = get_anchor_y (&worst_rect, get_opposite_mir_placement_gravity (impl->window_anchor));
2043++ final_position = get_anchor_y (&final_rect, get_opposite_mir_placement_gravity (impl->window_anchor));
2044++ flipped_offset = final_position - test_position;
2045++
2046++ if (ABS (flipped_offset) < ABS (unflipped_offset))
2047++ {
2048++ flipped_rect.y = worst_rect.y;
2049++ flipped_y = TRUE;
2050++ }
2051++ }
2052++
2053++ g_signal_emit_by_name (window,
2054++ "moved-to-rect",
2055++ &flipped_rect,
2056++ &final_rect,
2057++ flipped_x,
2058++ flipped_y);
2059++}
2060++
2061+ static void
2062+ gdk_mir_window_impl_set_background (GdkWindow *window,
2063+ cairo_pattern_t *pattern)
2064+--
2065+2.10.2
2066+
2067
2068=== modified file 'debian/patches/series'
2069--- debian/patches/series 2017-01-23 14:44:24 +0000
2070+++ debian/patches/series 2017-02-08 17:37:49 +0000
2071@@ -24,3 +24,14 @@
2072 unity-border-radius.patch
2073 unity-headerbar-maximized-mode.patch
2074 gtksocket-unscale-before-sending-configurenotify.patch
2075+
2076+0001-mir-implement-window-properties.patch
2077+0002-mir-track-focused-window.patch
2078+0003-mir-connect-to-content-hub.patch
2079+0004-mir-copy-clipboard-data-to-content-hub.patch
2080+0005-mir-paste-clipboard-data-from-content-hub.patch
2081+0006-mir-properly-handle-empty-clipboard.patch
2082+0031-mir-fix-compile-time-warnings.patch
2083+0032-mir-use-modal-window-hint.patch
2084+0036-mir-use-mir_surface_spec_set_placement-for-menus.patch
2085+0037-mir-handle-surface-placement-events.patch

Subscribers

People subscribed via source and target branches

to all changes: