Merge lp:~unity-team/compiz/x-sru5 into lp:compiz/0.9.13

Proposed by Marco Trevisan (Treviño) on 2017-06-27
Status: Superseded
Proposed branch: lp:~unity-team/compiz/x-sru5
Merge into: lp:compiz/0.9.13
Diff against target: 1684 lines (+1650/-0) (has conflicts)
3 files modified
debian/changelog (+93/-0)
gtk/window-decorator/decorator.c (+2/-0)
gtk/window-decorator/metacity.c.OTHER (+1555/-0)
Text conflict in debian/changelog
Contents conflict in gtk/window-decorator/metacity.c
To merge this branch: bzr merge lp:~unity-team/compiz/x-sru5
Reviewer Review Type Date Requested Status
Compiz Maintainers 2017-06-27 Pending
Review via email: mp+326393@code.launchpad.net

Commit message

Releasing SRU5 for Ubuntu 16.04

To post a comment you must log in.
lp:~unity-team/compiz/x-sru5 updated on 2017-11-16
4027. By Marco Trevisan (Treviño) on 2017-06-28

unity-lowgfx: use better effect for grid

4028. By Marco Trevisan (Treviño) on 2017-06-28

debian/changelog: add missing bug references

4029. By Alberts Muktupāvels on 2017-07-04

Use AnyPropertyType when getting _MOTIF_WM_HINTS property.

4030. By Marco Trevisan (Treviño) on 2017-07-03

move: damage all the border area in outline mode and ignore transparent colors

Also we don't really need to damage at every X event. It's just about doing it
right the firs time, by including the exceeding space.
Also optimize damanging in outline-mode, by only touching such regions

Plus add some optimizations when not blending, as we don't care about the alpha channel

4031. By Marco Trevisan (Treviño) on 2017-07-03

grid: ignore alpha in colors when not blending, and fix animations

The fade-out animation was still happening when the duration was set to 1,
while it was broken when it was 0. Fixed both.

In unity-lowgfx.ini set the animation duration to 0 in grid and d not
draw stretched windows. Enable blending again as it's really not
expensive in this case, while not having it, really makes the user
experience a lot poorer.

4032. By Marco Trevisan (Treviño) on 2017-07-03

resize: add support for disabling transparency and avoid over-damaging in outline mode

4033. By Marco Trevisan (Treviño) on 2017-07-03

Screen: add averageColor to get the current desktop average color

We get the value from the root window and we parse it using regex.
Also use this in 'move', 'resize' and 'grid' plugins by default, doing the
appropriate lightening / darkening to make this working properly
on the desktop surface

4034. By Marco Trevisan (Treviño) on 2017-07-04

Bumping micro version

4035. By Marco Trevisan (Treviño) on 2017-07-07

debian: go back setting COMPIZ_CONFIG_PROFILE in X11 scripts

4036. By Marco Trevisan (Treviño) on 2017-07-20

debian: tune unity-lowgfx profile and add upgrades

4037. By Marco Trevisan (Treviño) on 2017-11-16

unity-lowgfx.ini: remove unsupported unity option

Unmerged revisions

4037. By Marco Trevisan (Treviño) on 2017-11-16

unity-lowgfx.ini: remove unsupported unity option

4036. By Marco Trevisan (Treviño) on 2017-07-20

debian: tune unity-lowgfx profile and add upgrades

4035. By Marco Trevisan (Treviño) on 2017-07-07

debian: go back setting COMPIZ_CONFIG_PROFILE in X11 scripts

4034. By Marco Trevisan (Treviño) on 2017-07-04

Bumping micro version

4033. By Marco Trevisan (Treviño) on 2017-07-03

Screen: add averageColor to get the current desktop average color

We get the value from the root window and we parse it using regex.
Also use this in 'move', 'resize' and 'grid' plugins by default, doing the
appropriate lightening / darkening to make this working properly
on the desktop surface

4032. By Marco Trevisan (Treviño) on 2017-07-03

resize: add support for disabling transparency and avoid over-damaging in outline mode

4031. By Marco Trevisan (Treviño) on 2017-07-03

grid: ignore alpha in colors when not blending, and fix animations

The fade-out animation was still happening when the duration was set to 1,
while it was broken when it was 0. Fixed both.

In unity-lowgfx.ini set the animation duration to 0 in grid and d not
draw stretched windows. Enable blending again as it's really not
expensive in this case, while not having it, really makes the user
experience a lot poorer.

4030. By Marco Trevisan (Treviño) on 2017-07-03

move: damage all the border area in outline mode and ignore transparent colors

Also we don't really need to damage at every X event. It's just about doing it
right the firs time, by including the exceeding space.
Also optimize damanging in outline-mode, by only touching such regions

Plus add some optimizations when not blending, as we don't care about the alpha channel

4029. By Alberts Muktupāvels on 2017-07-04

Use AnyPropertyType when getting _MOTIF_WM_HINTS property.

4028. By Marco Trevisan (Treviño) on 2017-06-28

debian/changelog: add missing bug references

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-06-16 15:17:48 +0000
3+++ debian/changelog 2017-06-27 23:27:37 +0000
4@@ -1,3 +1,4 @@
5+<<<<<<< TREE
6 compiz (1:0.9.13.1+17.10.20170616-0ubuntu1) artful; urgency=medium
7
8 [ Martin Wimpress ]
9@@ -326,6 +327,98 @@
10
11 -- Matthias Klose <doko@ubuntu.com> Sat, 23 Apr 2016 00:01:37 +0000
12
13+=======
14+compiz (1:0.9.12.2+16.04.20160823-0ubuntu2) UNRELEASED; urgency=medium
15+
16+ [ Eleni Maria Stea ]
17+ * Added option to disable blend in grid plugin
18+ * Move: add options for showing only the window shape (filled or not)
19+
20+ [ Marco Trevisan (Treviño) ]
21+ * debian/65compiz_profile-on-session: don't export
22+ COMPIZ_CONFIG_PROFILE in unity
23+
24+ [ Alberts Muktupāvels ]
25+ * Ensure that surfaces used by metacity theme have device scale set to
26+ 1 . (LP: #1530277) (LP: #1530277)
27+
28+ [ Martin Wimpress ]
29+ * mate: Avoid artefacts of Windows Thumbnail Previews (LP: #1606369)
30+
31+ -- Eleni Maria Stea <elenimaria.stea@canonical.com> Tue, 27 Jun 2017 18:49:59 +0200
32+
33+compiz (1:0.9.12.2+16.04.20160823-0ubuntu1) xenial; urgency=medium
34+
35+ [ Andrea Azzarone ]
36+ * [expo] limit scroll to workarea. (LP: #913880)
37+
38+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Tue, 23 Aug 2016 16:06:02 +0000
39+
40+compiz (1:0.9.12.2+16.04.20160801.3-0ubuntu1) xenial; urgency=medium
41+
42+ [ Andrea Azzarone ]
43+ * Don't activate expo if not needed (1x1 setup) (LP: #1606254)
44+ * Don't crash if gsettings key is not found. Default value will be
45+ used. (LP: #1044662)
46+ * focusDefaultWindow: focus Most Recently Used (MRU) window and
47+ fallback to the top window in case MRU list is not available. (LP:
48+ #1073488, LP: #1459671)
49+
50+ [ Marco Trevisan (Treviño) ]
51+ * Unity MigrationScript: sync gsettings on exit, and only use dconf on
52+ failure (LP: #1605011)
53+
54+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Mon, 01 Aug 2016 13:41:42 +0000
55+
56+compiz (1:0.9.12.2+16.04.20160714-0ubuntu1) xenial; urgency=medium
57+
58+ [ Eleni Maria Stea ]
59+ * Added options for no animation in expo and scale plugins. They skip
60+ the intermediate fading steps that force several redraws.
61+ * Added a new option in show desktop plugin that skips the fade
62+ animation: useful when performance is more important than eyecandy.
63+
64+ [ Marco Trevisan (Treviño) ]
65+ * debian: add unity-lowgfx profile to compizconfig (LP: #1598770)
66+ * Composite: use C++ goodness for managing damaging rectangles
67+ * ccsGSettingsBackend: don't try to update setting if wrapper is not
68+ found
69+ * migration scripts: remove unsupported plugins for all the unity
70+ profiles
71+
72+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Thu, 14 Jul 2016 16:00:57 +0000
73+
74+compiz (1:0.9.12.2+16.04.20160526-0ubuntu1) xenial; urgency=medium
75+
76+ [ Andrea Azzarone ]
77+ * Add an option to notify that a key press is actually an "auto
78+ repeat" one. (LP: #1572241)
79+
80+ [ Alberts Muktupāvels ]
81+ * OpenGL: use the number of Opaque windows around to decide whether
82+ paint the bg or not (LP: #1574866)
83+
84+ [ Marco Trevisan (Treviño) ]
85+ * Scale: use the selectedWindow as starting point when focusing a
86+ window (LP: #1575168)
87+ * Scale: allow to iterate through windows using Tab key
88+ * Window: call stateChangeNotify when compiz state changed but before
89+ changing the WM state (LP: #1521302)
90+
91+ [ Eleni Maria Stea ]
92+ * Expo, Scale: add support for bottom offsets (LP: #1562346, LP:
93+ #1573897)
94+
95+ [ handsome_feng ]
96+ * Add a YBottomOffset value when stretch maximized windows。 (LP:
97+ #1562348)
98+
99+ [ CI Train Bot ]
100+ * No-change rebuild.
101+
102+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Thu, 26 May 2016 00:12:16 +0000
103+
104+>>>>>>> MERGE-SOURCE
105 compiz (1:0.9.12.2+16.04.20160415-0ubuntu1) xenial; urgency=medium
106
107 [ Martin Wimpress ]
108
109=== modified file 'debian/mate.ini'
110=== modified file 'gtk/window-decorator/decorator.c'
111--- gtk/window-decorator/decorator.c 2017-04-02 17:32:10 +0000
112+++ gtk/window-decorator/decorator.c 2017-06-27 23:27:37 +0000
113@@ -553,6 +553,8 @@
114 }
115 #endif
116
117+ // FIXME: this should match the current monitor scaling!
118+ cairo_surface_set_device_scale (buffer_surface, 1, 1);
119 gdk_flush ();
120
121 /* Handle failure */
122
123=== added file 'gtk/window-decorator/metacity.c.OTHER'
124--- gtk/window-decorator/metacity.c.OTHER 1970-01-01 00:00:00 +0000
125+++ gtk/window-decorator/metacity.c.OTHER 2017-06-27 23:27:37 +0000
126@@ -0,0 +1,1555 @@
127+/*
128+ * Copyright © 2006 Novell, Inc.
129+ *
130+ * This library is free software; you can redistribute it and/or
131+ * modify it under the terms of the GNU Lesser General Public
132+ * License as published by the Free Software Foundation; either
133+ * version 2 of the License, or (at your option) any later version.
134+ *
135+ * This library is distributed in the hope that it will be useful,
136+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
137+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
138+ * Lesser General Public License for more details.
139+ *
140+ * You should have received a copy of the GNU Lesser General Public
141+ * License along with this library; if not, write to the
142+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
143+ * Boston, MA 02111-1307, USA.
144+ *
145+ * Author: David Reveman <davidr@novell.com>
146+ *
147+ * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com>
148+ * Frames Management: Copright © 2011 Canonical Ltd.
149+ * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
150+ */
151+
152+#include "gtk-window-decorator.h"
153+
154+#ifdef USE_METACITY
155+
156+MetaButtonLayout meta_button_layout;
157+
158+static gboolean
159+meta_button_present (MetaButtonLayout *button_layout,
160+ MetaButtonFunction function)
161+{
162+ int i;
163+
164+ for (i = 0; i < MAX_BUTTONS_PER_CORNER; ++i)
165+ if (button_layout->left_buttons[i] == function)
166+ return TRUE;
167+
168+ for (i = 0; i < MAX_BUTTONS_PER_CORNER; ++i)
169+ if (button_layout->right_buttons[i] == function)
170+ return TRUE;
171+
172+ return FALSE;
173+}
174+
175+static void
176+decor_update_meta_window_property (decor_t *d,
177+ MetaTheme *theme,
178+ MetaFrameFlags flags,
179+ MetaFrameType type,
180+ Region top,
181+ Region bottom,
182+ Region left,
183+ Region right)
184+{
185+ long *data;
186+ GdkDisplay *display;
187+ Display *xdisplay;
188+ gint nQuad;
189+ decor_extents_t win_extents;
190+ decor_extents_t frame_win_extents;
191+ decor_extents_t max_win_extents;
192+ decor_extents_t frame_max_win_extents;
193+ decor_quad_t quads[N_QUADS_MAX];
194+ unsigned int nOffset;
195+ unsigned int frame_type;
196+ unsigned int frame_state;
197+ unsigned int frame_actions;
198+ gint w;
199+ gint lh;
200+ gint rh;
201+ gint top_stretch_offset;
202+ gint bottom_stretch_offset;
203+ gint left_stretch_offset;
204+ gint right_stretch_offset;
205+
206+ display = gdk_display_get_default ();
207+ xdisplay = gdk_x11_display_get_xdisplay (display);
208+
209+ nOffset = 1;
210+
211+ frame_type = populate_frame_type (d);
212+ frame_state = populate_frame_state (d);
213+ frame_actions = populate_frame_actions (d);
214+
215+ win_extents = frame_win_extents = d->frame->win_extents;
216+ max_win_extents = frame_max_win_extents = d->frame->max_win_extents;
217+
218+ /* Add the invisible grab area padding, but only for
219+ * pixmap type decorations */
220+ if (!d->frame_window)
221+ {
222+ GdkScreen *screen;
223+ MetaStyleInfo *style_info;
224+ MetaFrameBorders borders;
225+
226+ screen = gtk_widget_get_screen (d->frame->style_window_rgba);
227+ style_info = meta_theme_create_style_info (screen, d->gtk_theme_variant);
228+
229+ meta_theme_get_frame_borders (theme, style_info, type,
230+ d->frame->text_height,
231+ flags, &borders);
232+
233+ if (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE)
234+ {
235+ frame_win_extents.left += borders.invisible.left;
236+ frame_win_extents.right += borders.invisible.right;
237+ frame_max_win_extents.left += borders.invisible.left;
238+ frame_max_win_extents.right += borders.invisible.right;
239+ }
240+
241+ if (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE)
242+ {
243+ frame_win_extents.bottom += borders.invisible.bottom;
244+ frame_win_extents.top += borders.invisible.top;
245+ frame_max_win_extents.bottom += borders.invisible.bottom;
246+ frame_max_win_extents.top += borders.invisible.top;
247+ }
248+
249+ meta_style_info_unref (style_info);
250+ }
251+
252+ w = d->border_layout.top.x2 - d->border_layout.top.x1 -
253+ d->context->left_space - d->context->right_space;
254+
255+ if (d->border_layout.rotation)
256+ lh = d->border_layout.left.x2 - d->border_layout.left.x1;
257+ else
258+ lh = d->border_layout.left.y2 - d->border_layout.left.y1;
259+
260+ if (d->border_layout.rotation)
261+ rh = d->border_layout.right.x2 - d->border_layout.right.x1;
262+ else
263+ rh = d->border_layout.right.y2 - d->border_layout.right.y1;
264+
265+ left_stretch_offset = lh / 2;
266+ right_stretch_offset = rh / 2;
267+ top_stretch_offset = w - d->button_width - 1;
268+ bottom_stretch_offset = (d->border_layout.bottom.x2 - d->border_layout.bottom.x1 -
269+ d->context->left_space - d->context->right_space) / 2;
270+
271+ nQuad = decor_set_lXrXtXbX_window_quads (quads, d->context, &d->border_layout,
272+ left_stretch_offset, right_stretch_offset,
273+ top_stretch_offset, bottom_stretch_offset);
274+
275+ win_extents.top += d->frame->titlebar_height;
276+ frame_win_extents.top += d->frame->titlebar_height;
277+ max_win_extents.top += d->frame->max_titlebar_height;
278+ frame_max_win_extents.top += d->frame->max_titlebar_height;
279+
280+ if (d->frame_window)
281+ {
282+ data = decor_alloc_property (nOffset, WINDOW_DECORATION_TYPE_WINDOW);
283+ decor_gen_window_property (data, nOffset - 1, &win_extents, &max_win_extents,
284+ 20, 20, frame_type, frame_state, frame_actions);
285+ }
286+ else
287+ {
288+ data = decor_alloc_property (nOffset, WINDOW_DECORATION_TYPE_PIXMAP);
289+ decor_quads_to_property (data, nOffset - 1, cairo_xlib_surface_get_drawable (d->surface),
290+ &frame_win_extents, &win_extents,
291+ &frame_max_win_extents, &max_win_extents,
292+ ICON_SPACE + d->button_width,
293+ 0, quads, nQuad, frame_type, frame_state, frame_actions);
294+ }
295+
296+ gdk_error_trap_push ();
297+
298+ XChangeProperty (xdisplay, d->prop_xid, win_decor_atom, XA_INTEGER,
299+ 32, PropModeReplace, (guchar *) data,
300+ PROP_HEADER_SIZE + BASE_PROP_SIZE + QUAD_PROP_SIZE * N_QUADS_MAX);
301+ gdk_display_sync (display);
302+
303+ gdk_error_trap_pop_ignored ();
304+
305+ free (data);
306+
307+ decor_update_blur_property (d, w, lh,
308+ top, top_stretch_offset,
309+ bottom, bottom_stretch_offset,
310+ left, left_stretch_offset,
311+ right, right_stretch_offset);
312+}
313+
314+static void
315+meta_get_corner_radius (const MetaFrameGeometry *fgeom,
316+ int *top_left_radius,
317+ int *top_right_radius,
318+ int *bottom_left_radius,
319+ int *bottom_right_radius)
320+{
321+ *top_left_radius = fgeom->top_left_corner_rounded_radius;
322+ *top_right_radius = fgeom->top_right_corner_rounded_radius;
323+ *bottom_left_radius = fgeom->bottom_left_corner_rounded_radius;
324+ *bottom_right_radius = fgeom->bottom_right_corner_rounded_radius;
325+}
326+
327+static int
328+radius_to_width (int radius,
329+ int i)
330+{
331+ float r1 = sqrt (radius) + radius;
332+ float r2 = r1 * r1 - (r1 - (i + 0.5)) * (r1 - (i + 0.5));
333+
334+ return floor (0.5f + r1 - sqrt (r2));
335+}
336+
337+static Region
338+meta_get_top_border_region (const MetaFrameGeometry *fgeom,
339+ int width)
340+{
341+ Region corners_xregion;
342+ Region border_xregion;
343+ XRectangle xrect;
344+ int top_left_radius;
345+ int top_right_radius;
346+ int bottom_left_radius;
347+ int bottom_right_radius;
348+ int w;
349+ int i;
350+ int height;
351+
352+ corners_xregion = XCreateRegion ();
353+
354+ meta_get_corner_radius (fgeom, &top_left_radius, &top_right_radius,
355+ &bottom_left_radius, &bottom_right_radius);
356+
357+ width = width - fgeom->borders.invisible.left - fgeom->borders.invisible.right;
358+ height = fgeom->borders.visible.top;
359+
360+ if (top_left_radius)
361+ {
362+ for (i = 0; i < top_left_radius; ++i)
363+ {
364+ w = radius_to_width (top_left_radius, i);
365+
366+ xrect.x = 0;
367+ xrect.y = i;
368+ xrect.width = w;
369+ xrect.height = 1;
370+
371+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
372+ }
373+ }
374+
375+ if (top_right_radius)
376+ {
377+ for (i = 0; i < top_right_radius; ++i)
378+ {
379+ w = radius_to_width (top_right_radius, i);
380+
381+ xrect.x = width - w;
382+ xrect.y = i;
383+ xrect.width = w;
384+ xrect.height = 1;
385+
386+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
387+ }
388+ }
389+
390+ border_xregion = XCreateRegion ();
391+
392+ xrect.x = 0;
393+ xrect.y = 0;
394+ xrect.width = width;
395+ xrect.height = height;
396+
397+ XUnionRectWithRegion (&xrect, border_xregion, border_xregion);
398+
399+ XSubtractRegion (border_xregion, corners_xregion, border_xregion);
400+
401+ XDestroyRegion (corners_xregion);
402+
403+ return border_xregion;
404+}
405+
406+static Region
407+meta_get_bottom_border_region (const MetaFrameGeometry *fgeom,
408+ int width)
409+{
410+ Region corners_xregion;
411+ Region border_xregion;
412+ XRectangle xrect;
413+ int top_left_radius;
414+ int top_right_radius;
415+ int bottom_left_radius;
416+ int bottom_right_radius;
417+ int w;
418+ int i;
419+ int height;
420+
421+ corners_xregion = XCreateRegion ();
422+
423+ meta_get_corner_radius (fgeom, &top_left_radius, &top_right_radius,
424+ &bottom_left_radius, &bottom_right_radius);
425+
426+ width = width - fgeom->borders.invisible.left - fgeom->borders.invisible.right;
427+ height = fgeom->borders.visible.bottom;
428+
429+ if (bottom_left_radius)
430+ {
431+ for (i = 0; i < bottom_left_radius; ++i)
432+ {
433+ w = radius_to_width (bottom_left_radius, i);
434+
435+ xrect.x = 0;
436+ xrect.y = height - i - 1;
437+ xrect.width = w;
438+ xrect.height = 1;
439+
440+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
441+ }
442+ }
443+
444+ if (bottom_right_radius)
445+ {
446+ for (i = 0; i < bottom_right_radius; ++i)
447+ {
448+ w = radius_to_width (bottom_right_radius, i);
449+
450+ xrect.x = width - w;
451+ xrect.y = height - i - 1;
452+ xrect.width = w;
453+ xrect.height = 1;
454+
455+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
456+ }
457+ }
458+
459+ border_xregion = XCreateRegion ();
460+
461+ xrect.x = 0;
462+ xrect.y = 0;
463+ xrect.width = width;
464+ xrect.height = height;
465+
466+ XUnionRectWithRegion (&xrect, border_xregion, border_xregion);
467+
468+ XSubtractRegion (border_xregion, corners_xregion, border_xregion);
469+
470+ XDestroyRegion (corners_xregion);
471+
472+ return border_xregion;
473+}
474+
475+static Region
476+meta_get_left_border_region (const MetaFrameGeometry *fgeom,
477+ int height)
478+{
479+ Region border_xregion;
480+ XRectangle xrect;
481+
482+ border_xregion = XCreateRegion ();
483+
484+ xrect.x = 0;
485+ xrect.y = 0;
486+ xrect.width = fgeom->borders.visible.left;
487+ xrect.height = height - fgeom->borders.total.top - fgeom->borders.total.bottom;
488+
489+ XUnionRectWithRegion (&xrect, border_xregion, border_xregion);
490+
491+ return border_xregion;
492+}
493+
494+static Region
495+meta_get_right_border_region (const MetaFrameGeometry *fgeom,
496+ int height)
497+{
498+ Region border_xregion;
499+ XRectangle xrect;
500+
501+ border_xregion = XCreateRegion ();
502+
503+ xrect.x = 0;
504+ xrect.y = 0;
505+ xrect.width = fgeom->borders.visible.right;
506+ xrect.height = height - fgeom->borders.total.top - fgeom->borders.total.bottom;
507+
508+ XUnionRectWithRegion (&xrect, border_xregion, border_xregion);
509+
510+ return border_xregion;
511+}
512+
513+static MetaButtonState
514+meta_button_state (int state)
515+{
516+ if (state & IN_EVENT_WINDOW)
517+ {
518+ if (state & PRESSED_EVENT_WINDOW)
519+ return META_BUTTON_STATE_PRESSED;
520+
521+ return META_BUTTON_STATE_PRELIGHT;
522+ }
523+
524+ return META_BUTTON_STATE_NORMAL;
525+}
526+
527+static MetaButtonType
528+meta_function_to_type (MetaButtonFunction function)
529+{
530+ switch (function)
531+ {
532+ case META_BUTTON_FUNCTION_MENU:
533+ return META_BUTTON_TYPE_MENU;
534+ case META_BUTTON_FUNCTION_MINIMIZE:
535+ return META_BUTTON_TYPE_MINIMIZE;
536+ case META_BUTTON_FUNCTION_MAXIMIZE:
537+ return META_BUTTON_TYPE_MAXIMIZE;
538+ case META_BUTTON_FUNCTION_CLOSE:
539+ return META_BUTTON_TYPE_CLOSE;
540+ case META_BUTTON_FUNCTION_SHADE:
541+ return META_BUTTON_TYPE_SHADE;
542+ case META_BUTTON_FUNCTION_ABOVE:
543+ return META_BUTTON_TYPE_ABOVE;
544+ case META_BUTTON_FUNCTION_STICK:
545+ return META_BUTTON_TYPE_STICK;
546+ case META_BUTTON_FUNCTION_UNSHADE:
547+ return META_BUTTON_TYPE_UNSHADE;
548+ case META_BUTTON_FUNCTION_UNABOVE:
549+ return META_BUTTON_TYPE_UNABOVE;
550+ case META_BUTTON_FUNCTION_UNSTICK:
551+ return META_BUTTON_TYPE_UNSTICK;
552+ default:
553+ break;
554+ }
555+
556+ return META_BUTTON_TYPE_LAST;
557+}
558+
559+static MetaButtonState
560+meta_button_state_for_button_type (decor_t *d,
561+ MetaButtonType type)
562+{
563+ switch (type)
564+ {
565+ case META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND:
566+ type = meta_function_to_type (meta_button_layout.left_buttons[0]);
567+ break;
568+ case META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND:
569+ type = meta_function_to_type (meta_button_layout.left_buttons[1]);
570+ break;
571+ case META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND:
572+ type = meta_function_to_type (meta_button_layout.left_buttons[2]);
573+ break;
574+ case META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND:
575+ type = meta_function_to_type (meta_button_layout.right_buttons[0]);
576+ break;
577+ case META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND:
578+ type = meta_function_to_type (meta_button_layout.right_buttons[1]);
579+ break;
580+ case META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND:
581+ type = meta_function_to_type (meta_button_layout.right_buttons[2]);
582+ default:
583+ break;
584+ }
585+
586+ switch (type)
587+ {
588+ case META_BUTTON_TYPE_CLOSE:
589+ return meta_button_state (d->button_states[BUTTON_CLOSE]);
590+ case META_BUTTON_TYPE_MAXIMIZE:
591+ return meta_button_state (d->button_states[BUTTON_MAX]);
592+ case META_BUTTON_TYPE_MINIMIZE:
593+ return meta_button_state (d->button_states[BUTTON_MIN]);
594+ case META_BUTTON_TYPE_MENU:
595+ return meta_button_state (d->button_states[BUTTON_MENU]);
596+ case META_BUTTON_TYPE_SHADE:
597+ return meta_button_state (d->button_states[BUTTON_SHADE]);
598+ case META_BUTTON_TYPE_ABOVE:
599+ return meta_button_state (d->button_states[BUTTON_ABOVE]);
600+ case META_BUTTON_TYPE_STICK:
601+ return meta_button_state (d->button_states[BUTTON_STICK]);
602+ case META_BUTTON_TYPE_UNSHADE:
603+ return meta_button_state (d->button_states[BUTTON_UNSHADE]);
604+ case META_BUTTON_TYPE_UNABOVE:
605+ return meta_button_state (d->button_states[BUTTON_UNABOVE]);
606+ case META_BUTTON_TYPE_UNSTICK:
607+ return meta_button_state (d->button_states[BUTTON_UNSTICK]);
608+ default:
609+ break;
610+ }
611+
612+ return META_BUTTON_STATE_NORMAL;
613+}
614+
615+static void
616+meta_get_decoration_geometry (decor_t *d,
617+ MetaTheme *theme,
618+ MetaFrameFlags *flags,
619+ MetaFrameGeometry *fgeom,
620+ MetaButtonLayout *button_layout,
621+ MetaFrameType frame_type)
622+{
623+ GdkScreen *screen;
624+ MetaStyleInfo *style_info;
625+ gint client_width;
626+ gint client_height;
627+
628+ if (!(frame_type < META_FRAME_TYPE_LAST))
629+ frame_type = META_FRAME_TYPE_NORMAL;
630+
631+ if (meta_button_layout_set)
632+ {
633+ *button_layout = meta_button_layout;
634+ }
635+ else
636+ {
637+ gint i;
638+
639+ button_layout->left_buttons[0] = META_BUTTON_FUNCTION_MENU;
640+
641+ for (i = 1; i < MAX_BUTTONS_PER_CORNER; ++i)
642+ button_layout->left_buttons[i] = META_BUTTON_FUNCTION_LAST;
643+
644+ button_layout->right_buttons[0] = META_BUTTON_FUNCTION_MINIMIZE;
645+ button_layout->right_buttons[1] = META_BUTTON_FUNCTION_MAXIMIZE;
646+ button_layout->right_buttons[2] = META_BUTTON_FUNCTION_CLOSE;
647+
648+ for (i = 3; i < MAX_BUTTONS_PER_CORNER; ++i)
649+ button_layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST;
650+ }
651+
652+ *flags = 0;
653+
654+ if (d->actions & WNCK_WINDOW_ACTION_CLOSE)
655+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_DELETE;
656+
657+ if (d->actions & WNCK_WINDOW_ACTION_MINIMIZE)
658+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MINIMIZE;
659+
660+ if (d->actions & WNCK_WINDOW_ACTION_MAXIMIZE)
661+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MAXIMIZE;
662+
663+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MENU;
664+
665+ if (d->actions & WNCK_WINDOW_ACTION_RESIZE)
666+ {
667+ if (!(d->state & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY))
668+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_VERTICAL_RESIZE;
669+ if (!(d->state & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY))
670+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_HORIZONTAL_RESIZE;
671+ }
672+
673+ if (d->actions & WNCK_WINDOW_ACTION_MOVE)
674+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MOVE;
675+
676+ if (d->actions & WNCK_WINDOW_ACTION_MAXIMIZE)
677+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_MAXIMIZE;
678+
679+ if (d->actions & WNCK_WINDOW_ACTION_SHADE)
680+ *flags |= (MetaFrameFlags ) META_FRAME_ALLOWS_SHADE;
681+
682+ if (d->active)
683+ *flags |= (MetaFrameFlags ) META_FRAME_HAS_FOCUS;
684+
685+ if ((d->state & META_MAXIMIZED) == META_MAXIMIZED)
686+ *flags |= (MetaFrameFlags ) META_FRAME_MAXIMIZED;
687+
688+ if (d->state & WNCK_WINDOW_STATE_STICKY)
689+ *flags |= (MetaFrameFlags ) META_FRAME_STUCK;
690+
691+ if (d->state & WNCK_WINDOW_STATE_FULLSCREEN)
692+ *flags |= (MetaFrameFlags ) META_FRAME_FULLSCREEN;
693+
694+ if (d->state & WNCK_WINDOW_STATE_SHADED)
695+ *flags |= (MetaFrameFlags ) META_FRAME_SHADED;
696+
697+ if (d->state & WNCK_WINDOW_STATE_ABOVE)
698+ *flags |= (MetaFrameFlags ) META_FRAME_ABOVE;
699+
700+ client_width = d->border_layout.top.x2 - d->border_layout.top.x1;
701+ client_width -= d->context->right_space + d->context->left_space;
702+
703+ if (d->border_layout.rotation)
704+ client_height = d->border_layout.left.x2 - d->border_layout.left.x1;
705+ else
706+ client_height = d->border_layout.left.y2 - d->border_layout.left.y1;
707+
708+ screen = gtk_widget_get_screen (d->frame->style_window_rgba);
709+ style_info = meta_theme_create_style_info (screen, d->gtk_theme_variant);
710+
711+ meta_theme_calc_geometry (theme, style_info, frame_type, d->frame->text_height,
712+ *flags, client_width, client_height,
713+ button_layout, fgeom);
714+
715+ meta_style_info_unref (style_info);
716+}
717+
718+void
719+meta_draw_window_decoration (decor_t *d)
720+{
721+ GdkDisplay *display;
722+ GdkScreen *screen;
723+ Display *xdisplay;
724+ cairo_surface_t *surface;
725+ Picture src;
726+ MetaButtonState button_states [META_BUTTON_TYPE_LAST];
727+ MetaButtonLayout button_layout;
728+ MetaFrameGeometry fgeom;
729+ MetaFrameFlags flags;
730+ MetaFrameType frame_type;
731+ MetaTheme *theme;
732+ MetaStyleInfo *style_info;
733+ GtkStyleContext *context;
734+ cairo_t *cr;
735+ gint i;
736+ Region top_region;
737+ Region bottom_region;
738+ Region left_region;
739+ Region right_region;
740+ gdouble meta_active_opacity;
741+ gdouble meta_inactive_opacity;
742+ gboolean meta_active_shade_opacity;
743+ gboolean meta_inactive_shade_opacity;
744+ double alpha;
745+ gboolean shade_alpha;
746+ MetaFrameStyle *frame_style;
747+ GtkWidget *style_window;
748+ GdkRGBA bg_rgba;
749+
750+ if (!d->surface || !d->picture)
751+ return;
752+
753+ display = gdk_display_get_default ();
754+ xdisplay = gdk_x11_display_get_xdisplay (display);
755+
756+ top_region = NULL;
757+ bottom_region = NULL;
758+ left_region = NULL;
759+ right_region = NULL;
760+
761+ g_object_get (settings, "metacity-active-opacity", &meta_active_opacity, NULL);
762+ g_object_get (settings, "metacity-inactive-opacity", &meta_inactive_opacity, NULL);
763+ g_object_get (settings, "metacity-active-shade-opacity", &meta_active_shade_opacity, NULL);
764+ g_object_get (settings, "metacity-inactive-shade-opacity", &meta_inactive_shade_opacity, NULL);
765+
766+ alpha = (d->active) ? meta_active_opacity : meta_inactive_opacity;
767+ shade_alpha = (d->active) ? meta_active_shade_opacity : meta_inactive_shade_opacity;
768+
769+ if (decoration_alpha == 1.0)
770+ alpha = 1.0;
771+
772+ if (cairo_xlib_surface_get_depth (d->surface) == 32)
773+ style_window = d->frame->style_window_rgba;
774+ else
775+ style_window = d->frame->style_window_rgb;
776+
777+ context = gtk_widget_get_style_context (style_window);
778+
779+ cr = cairo_create (d->buffer_surface ? d->buffer_surface : d->surface);
780+
781+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
782+
783+ theme = meta_theme_get_current ();
784+
785+ frame_type = meta_frame_type_from_string (d->frame->type);
786+
787+ if (frame_type == META_FRAME_TYPE_LAST)
788+ frame_type = META_FRAME_TYPE_NORMAL;
789+
790+ meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
791+ frame_type);
792+
793+ if ((d->prop_xid || !d->buffer_surface) && !d->frame_window)
794+ draw_shadow_background (d, cr, d->shadow, d->context);
795+
796+ for (i = 0; i < META_BUTTON_TYPE_LAST; ++i)
797+ button_states[i] = meta_button_state_for_button_type (d, i);
798+
799+ frame_style = meta_theme_get_frame_style (theme, frame_type, flags);
800+
801+ gtk_style_context_get_background_color (context, GTK_STATE_FLAG_NORMAL, &bg_rgba);
802+ bg_rgba.alpha = 1.0;
803+
804+ if (frame_style->window_background_color)
805+ {
806+ meta_color_spec_render (frame_style->window_background_color,
807+ context, &bg_rgba);
808+
809+ bg_rgba.alpha = frame_style->window_background_alpha / 255.0;
810+ }
811+
812+ /* Draw something that will be almost invisible to user. This is hacky way
813+ * to fix invisible decorations. */
814+ cairo_set_source_rgba (cr, 0, 0, 0, 0.01);
815+ cairo_rectangle (cr, 0, 0, 1, 1);
816+ cairo_fill (cr);
817+ /* ------------ */
818+
819+ cairo_destroy (cr);
820+
821+ if (d->frame_window)
822+ surface = create_surface (fgeom.width, fgeom.height, d->frame->style_window_rgb);
823+ else
824+ surface = create_surface (fgeom.width, fgeom.height, d->frame->style_window_rgba);
825+
826+ // FIXME: this should match the current monitor scaling!
827+ cairo_surface_set_device_scale (surface, 1, 1);
828+ cr = cairo_create (surface);
829+ gdk_cairo_set_source_rgba (cr, &bg_rgba);
830+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
831+
832+ src = XRenderCreatePicture (xdisplay, cairo_xlib_surface_get_drawable (surface),
833+ get_format_for_surface (d, surface), 0, NULL);
834+
835+ screen = gtk_widget_get_screen (d->frame->style_window_rgba);
836+ style_info = meta_theme_create_style_info (screen, d->gtk_theme_variant);
837+
838+ cairo_paint (cr);
839+ meta_theme_draw_frame (theme, style_info, cr, frame_type, flags,
840+ fgeom.width - fgeom.borders.total.left - fgeom.borders.total.right,
841+ fgeom.height - fgeom.borders.total.top - fgeom.borders.total.bottom,
842+ d->layout, d->frame->text_height, &button_layout,
843+ button_states, d->icon_pixbuf, NULL);
844+
845+ meta_style_info_unref (style_info);
846+
847+ if (fgeom.borders.visible.top)
848+ {
849+ top_region = meta_get_top_border_region (&fgeom, fgeom.width);
850+
851+ decor_blend_border_picture (xdisplay, d->context, src,
852+ fgeom.borders.invisible.left,
853+ fgeom.borders.invisible.top,
854+ d->picture, &d->border_layout,
855+ BORDER_TOP, top_region,
856+ alpha * 0xffff, shade_alpha, 0);
857+ }
858+
859+ if (fgeom.borders.visible.bottom)
860+ {
861+ bottom_region = meta_get_bottom_border_region (&fgeom, fgeom.width);
862+
863+ decor_blend_border_picture (xdisplay, d->context, src,
864+ fgeom.borders.invisible.left,
865+ fgeom.height - fgeom.borders.total.bottom,
866+ d->picture, &d->border_layout,
867+ BORDER_BOTTOM, bottom_region,
868+ alpha * 0xffff, shade_alpha, 0);
869+ }
870+
871+ if (fgeom.borders.visible.left)
872+ {
873+ left_region = meta_get_left_border_region (&fgeom, fgeom.height);
874+
875+ decor_blend_border_picture (xdisplay, d->context, src,
876+ fgeom.borders.invisible.left,
877+ fgeom.borders.total.top,
878+ d->picture, &d->border_layout,
879+ BORDER_LEFT, left_region,
880+ alpha * 0xffff, shade_alpha, 0);
881+ }
882+
883+ if (fgeom.borders.visible.right)
884+ {
885+ right_region = meta_get_right_border_region (&fgeom, fgeom.height);
886+
887+ decor_blend_border_picture (xdisplay, d->context, src,
888+ fgeom.width - fgeom.borders.total.right,
889+ fgeom.borders.total.top,
890+ d->picture, &d->border_layout,
891+ BORDER_RIGHT, right_region,
892+ alpha * 0xffff, shade_alpha, 0);
893+ }
894+
895+ cairo_destroy (cr);
896+ cairo_surface_destroy (surface);
897+ XRenderFreePicture (xdisplay, src);
898+
899+ copy_to_front_buffer (d);
900+
901+ if (d->frame_window)
902+ {
903+ GdkWindow *gdk_frame_window;
904+ GdkPixbuf *pixbuf;
905+
906+ gdk_frame_window = gtk_widget_get_window (d->decor_window);
907+
908+ pixbuf = gdk_pixbuf_get_from_surface (d->surface, 0, 0, d->width, d->height);
909+ gtk_image_set_from_pixbuf (GTK_IMAGE (d->decor_image), pixbuf);
910+ g_object_unref (pixbuf);
911+
912+ gdk_window_move_resize (gdk_frame_window,
913+ d->context->left_corner_space - 1,
914+ d->context->top_corner_space - 1,
915+ d->width,
916+ d->height);
917+
918+ gdk_window_lower (gdk_frame_window);
919+ }
920+
921+ if (d->prop_xid)
922+ {
923+ /* translate from frame to client window space */
924+ if (top_region)
925+ XOffsetRegion (top_region, -fgeom.borders.total.left, -fgeom.borders.total.top);
926+ if (bottom_region)
927+ XOffsetRegion (bottom_region, -fgeom.borders.total.left, 0);
928+ if (left_region)
929+ XOffsetRegion (left_region, -fgeom.borders.total.left, 0);
930+
931+ decor_update_meta_window_property (d, theme, flags, frame_type,
932+ top_region, bottom_region,
933+ left_region, right_region);
934+
935+ d->prop_xid = 0;
936+ }
937+
938+ if (top_region)
939+ XDestroyRegion (top_region);
940+ if (bottom_region)
941+ XDestroyRegion (bottom_region);
942+ if (left_region)
943+ XDestroyRegion (left_region);
944+ if (right_region)
945+ XDestroyRegion (right_region);
946+}
947+
948+static void
949+meta_calc_button_size (decor_t *d)
950+{
951+ MetaTheme *theme;
952+ MetaFrameType frame_type;
953+ MetaFrameFlags flags;
954+ MetaFrameGeometry fgeom;
955+ MetaButtonLayout button_layout;
956+ gint i, min_x, x, y, w, h, width;
957+
958+ if (!d->context)
959+ {
960+ d->button_width = 0;
961+ return;
962+ }
963+
964+ theme = meta_theme_get_current ();
965+
966+ frame_type = meta_frame_type_from_string (d->frame->type);
967+ if (!(frame_type < META_FRAME_TYPE_LAST))
968+ frame_type = META_FRAME_TYPE_NORMAL;
969+
970+ meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
971+ frame_type);
972+
973+ width = d->border_layout.top.x2 - d->border_layout.top.x1 -
974+ d->context->left_space - d->context->right_space +
975+ fgeom.borders.total.left + fgeom.borders.total.right;
976+
977+ min_x = width;
978+
979+ for (i = 0; i < 3; ++i)
980+ {
981+ static guint button_actions[3] = {
982+ WNCK_WINDOW_ACTION_CLOSE,
983+ WNCK_WINDOW_ACTION_MAXIMIZE,
984+ WNCK_WINDOW_ACTION_MINIMIZE
985+ };
986+
987+ if (d->actions & button_actions[i])
988+ {
989+ if (meta_get_button_position (d, i, width, 256, &x, &y, &w, &h))
990+ {
991+ if (x > width / 2 && x < min_x)
992+ min_x = x;
993+ }
994+ }
995+ }
996+
997+ d->button_width = width - min_x;
998+}
999+
1000+static MetaButtonFunction
1001+button_to_meta_button_function (gint i)
1002+{
1003+ switch (i)
1004+ {
1005+ case BUTTON_MENU:
1006+ return META_BUTTON_FUNCTION_MENU;
1007+ case BUTTON_MIN:
1008+ return META_BUTTON_FUNCTION_MINIMIZE;
1009+ case BUTTON_MAX:
1010+ return META_BUTTON_FUNCTION_MAXIMIZE;
1011+ case BUTTON_CLOSE:
1012+ return META_BUTTON_FUNCTION_CLOSE;
1013+ case BUTTON_SHADE:
1014+ return META_BUTTON_FUNCTION_SHADE;
1015+ case BUTTON_ABOVE:
1016+ return META_BUTTON_FUNCTION_ABOVE;
1017+ case BUTTON_STICK:
1018+ return META_BUTTON_FUNCTION_STICK;
1019+ case BUTTON_UNSHADE:
1020+ return META_BUTTON_FUNCTION_UNSHADE;
1021+ case BUTTON_UNABOVE:
1022+ return META_BUTTON_FUNCTION_UNABOVE;
1023+ case BUTTON_UNSTICK:
1024+ return META_BUTTON_FUNCTION_UNSTICK;
1025+ default:
1026+ break;
1027+ }
1028+
1029+ return META_BUTTON_FUNCTION_LAST;
1030+}
1031+
1032+gboolean
1033+meta_get_button_position (decor_t *d,
1034+ gint i,
1035+ gint width,
1036+ gint height,
1037+ gint *x,
1038+ gint *y,
1039+ gint *w,
1040+ gint *h)
1041+{
1042+ MetaButtonLayout button_layout;
1043+ MetaFrameGeometry fgeom;
1044+ MetaFrameType frame_type;
1045+ MetaFrameFlags flags;
1046+ MetaTheme *theme;
1047+ MetaButtonFunction button_function;
1048+ MetaButtonSpace *space;
1049+
1050+ if (!d->context)
1051+ {
1052+ /* undecorated windows implicitly have no buttons */
1053+ return FALSE;
1054+ }
1055+
1056+ theme = meta_theme_get_current ();
1057+
1058+ frame_type = meta_frame_type_from_string (d->frame->type);
1059+ if (!(frame_type < META_FRAME_TYPE_LAST))
1060+ frame_type = META_FRAME_TYPE_NORMAL;
1061+
1062+ meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
1063+ frame_type);
1064+
1065+ button_function = button_to_meta_button_function (i);
1066+ if (!meta_button_present (&button_layout, button_function))
1067+ return FALSE;
1068+
1069+ switch (i)
1070+ {
1071+ case BUTTON_MENU:
1072+ space = &fgeom.menu_rect;
1073+ break;
1074+ case BUTTON_MIN:
1075+ space = &fgeom.min_rect;
1076+ break;
1077+ case BUTTON_MAX:
1078+ space = &fgeom.max_rect;
1079+ break;
1080+ case BUTTON_CLOSE:
1081+ space = &fgeom.close_rect;
1082+ break;
1083+ case BUTTON_SHADE:
1084+ space = &fgeom.shade_rect;
1085+ break;
1086+ case BUTTON_ABOVE:
1087+ space = &fgeom.above_rect;
1088+ break;
1089+ case BUTTON_STICK:
1090+ space = &fgeom.stick_rect;
1091+ break;
1092+ case BUTTON_UNSHADE:
1093+ space = &fgeom.unshade_rect;
1094+ break;
1095+ case BUTTON_UNABOVE:
1096+ space = &fgeom.unabove_rect;
1097+ break;
1098+ case BUTTON_UNSTICK:
1099+ space = &fgeom.unstick_rect;
1100+ break;
1101+ default:
1102+ return FALSE;
1103+ }
1104+
1105+ if (!space->clickable.width && !space->clickable.height)
1106+ return FALSE;
1107+
1108+ *x = space->clickable.x;
1109+ *y = space->clickable.y;
1110+ *w = space->clickable.width;
1111+ *h = space->clickable.height;
1112+
1113+ if (d->frame_window)
1114+ {
1115+ *x += d->frame->win_extents.left + 4;
1116+ *y += d->frame->win_extents.top + 2;
1117+ }
1118+
1119+ return TRUE;
1120+}
1121+
1122+gfloat
1123+meta_get_title_scale (decor_frame_t *frame)
1124+{
1125+ MetaTheme *theme;
1126+ MetaFrameType type;
1127+ MetaFrameFlags flags;
1128+
1129+ theme = meta_theme_get_current ();
1130+ type = meta_frame_type_from_string (frame->type);
1131+ flags = 0xc33; /* fixme */
1132+
1133+ if (type == META_FRAME_TYPE_LAST)
1134+ return 1.0f;
1135+
1136+ gfloat scale = meta_theme_get_title_scale (theme, type, flags);
1137+
1138+ return scale;
1139+}
1140+
1141+gboolean
1142+meta_calc_decoration_size (decor_t *d,
1143+ gint w,
1144+ gint h,
1145+ gint name_width,
1146+ gint *width,
1147+ gint *height)
1148+{
1149+ decor_layout_t layout;
1150+ decor_context_t *context;
1151+ decor_shadow_t *shadow;
1152+
1153+ if (!d->decorated)
1154+ return FALSE;
1155+
1156+ if ((d->state & META_MAXIMIZED) == META_MAXIMIZED)
1157+ {
1158+ if (!d->frame_window)
1159+ {
1160+ if (d->active)
1161+ {
1162+ context = &d->frame->max_window_context_active;
1163+ shadow = d->frame->max_border_shadow_active;
1164+ }
1165+ else
1166+ {
1167+ context = &d->frame->max_window_context_inactive;
1168+ shadow = d->frame->max_border_shadow_inactive;
1169+ }
1170+ }
1171+ else
1172+ {
1173+ context = &d->frame->max_window_context_no_shadow;
1174+ shadow = d->frame->max_border_no_shadow;
1175+ }
1176+ }
1177+ else
1178+ {
1179+ if (!d->frame_window)
1180+ {
1181+ if (d->active)
1182+ {
1183+ context = &d->frame->window_context_active;
1184+ shadow = d->frame->border_shadow_active;
1185+ }
1186+ else
1187+ {
1188+ context = &d->frame->window_context_inactive;
1189+ shadow = d->frame->border_shadow_inactive;
1190+ }
1191+ }
1192+ else
1193+ {
1194+ context = &d->frame->window_context_no_shadow;
1195+ shadow = d->frame->border_no_shadow;
1196+ }
1197+ }
1198+
1199+ if (!d->frame_window)
1200+ {
1201+ decor_get_best_layout (context, w, h, &layout);
1202+
1203+ if (context != d->context || memcmp (&layout, &d->border_layout, sizeof (layout)))
1204+ {
1205+ *width = layout.width;
1206+ *height = layout.height;
1207+
1208+ d->border_layout = layout;
1209+ d->context = context;
1210+ d->shadow = shadow;
1211+
1212+ meta_calc_button_size (d);
1213+
1214+ return TRUE;
1215+ }
1216+ }
1217+ else
1218+ {
1219+ if ((d->state & META_MAXIMIZED) == META_MAXIMIZED)
1220+ decor_get_default_layout (context, d->client_width,
1221+ d->client_height - d->frame->titlebar_height,
1222+ &layout);
1223+ else
1224+ decor_get_default_layout (context, d->client_width,
1225+ d->client_height, &layout);
1226+
1227+ *width = layout.width;
1228+ *height = layout.height;
1229+
1230+ d->border_layout = layout;
1231+ d->shadow = shadow;
1232+ d->context = context;
1233+
1234+ meta_calc_button_size (d);
1235+
1236+ return TRUE;
1237+ }
1238+
1239+ return FALSE;
1240+}
1241+
1242+#define TOP_RESIZE_HEIGHT 2
1243+#define RESIZE_EXTENDS 15
1244+
1245+void
1246+meta_get_event_window_position (decor_t *d,
1247+ gint i,
1248+ gint j,
1249+ gint width,
1250+ gint height,
1251+ gint *x,
1252+ gint *y,
1253+ gint *w,
1254+ gint *h)
1255+{
1256+ MetaButtonLayout button_layout;
1257+ MetaFrameGeometry fgeom;
1258+ MetaFrameFlags flags;
1259+ MetaTheme *theme;
1260+
1261+ theme = meta_theme_get_current ();
1262+
1263+ meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
1264+ meta_frame_type_from_string (d->frame->type));
1265+
1266+ width += fgeom.borders.total.right + fgeom.borders.total.left;
1267+ height += fgeom.borders.total.top + fgeom.borders.total.bottom;
1268+
1269+ switch (i)
1270+ {
1271+ case 2: /* bottom */
1272+ switch (j)
1273+ {
1274+ case 2: /* bottom right */
1275+ *x = width - fgeom.borders.total.right - RESIZE_EXTENDS;
1276+ *y = height - fgeom.borders.total.bottom - RESIZE_EXTENDS;
1277+
1278+ if (d->frame_window)
1279+ {
1280+ *x += d->frame->win_extents.left + 2;
1281+ *y += d->frame->win_extents.top + 2;
1282+ }
1283+
1284+ *w = fgeom.borders.total.right + RESIZE_EXTENDS;
1285+ *h = fgeom.borders.total.bottom + RESIZE_EXTENDS;
1286+ break;
1287+ case 1: /* bottom */
1288+ *x = fgeom.borders.total.left + RESIZE_EXTENDS;
1289+ *y = height - fgeom.borders.total.bottom;
1290+
1291+ if (d->frame_window)
1292+ *y += d->frame->win_extents.top + 2;
1293+
1294+ *w = width - fgeom.borders.total.left - fgeom.borders.total.right - (2 * RESIZE_EXTENDS);
1295+ *h = fgeom.borders.total.bottom;
1296+ break;
1297+ case 0: /* bottom left */
1298+ default:
1299+ *x = 0;
1300+ *y = height - fgeom.borders.total.bottom - RESIZE_EXTENDS;
1301+
1302+ if (d->frame_window)
1303+ {
1304+ *x += d->frame->win_extents.left + 4;
1305+ *y += d->frame->win_extents.bottom + 2;
1306+ }
1307+
1308+ *w = fgeom.borders.total.left + RESIZE_EXTENDS;
1309+ *h = fgeom.borders.total.bottom + RESIZE_EXTENDS;
1310+ break;
1311+ }
1312+ break;
1313+ case 1: /* middle */
1314+ switch (j)
1315+ {
1316+ case 2: /* right */
1317+ *x = width - fgeom.borders.total.right;
1318+ *y = fgeom.borders.total.top + RESIZE_EXTENDS;
1319+
1320+ if (d->frame_window)
1321+ *x += d->frame->win_extents.left + 2;
1322+
1323+ *w = fgeom.borders.total.right;
1324+ *h = height - fgeom.borders.total.top - fgeom.borders.total.bottom - (2 * RESIZE_EXTENDS);
1325+ break;
1326+ case 1: /* middle */
1327+ *x = fgeom.borders.total.left;
1328+ *y = fgeom.title_rect.y + TOP_RESIZE_HEIGHT;
1329+ *w = width - fgeom.borders.total.left - fgeom.borders.total.right;
1330+ *h = height - fgeom.top_titlebar_edge - fgeom.borders.total.bottom;
1331+ break;
1332+ case 0: /* left */
1333+ default:
1334+ *x = 0;
1335+ *y = fgeom.borders.total.top + RESIZE_EXTENDS;
1336+
1337+ if (d->frame_window)
1338+ *x += d->frame->win_extents.left + 4;
1339+
1340+ *w = fgeom.borders.total.left;
1341+ *h = height - fgeom.borders.total.top - fgeom.borders.total.bottom - (2 * RESIZE_EXTENDS);
1342+ break;
1343+ }
1344+ break;
1345+ case 0: /* top */
1346+ default:
1347+ switch (j)
1348+ {
1349+ case 2: /* top right */
1350+ *x = width - fgeom.borders.total.right - RESIZE_EXTENDS;
1351+ *y = 0;
1352+
1353+ if (d->frame_window)
1354+ {
1355+ *x += d->frame->win_extents.left + 2;
1356+ *y += d->frame->win_extents.top + 2 - fgeom.title_rect.height;
1357+ }
1358+
1359+ *w = fgeom.borders.total.right + RESIZE_EXTENDS;
1360+ *h = fgeom.borders.total.top + RESIZE_EXTENDS;
1361+ break;
1362+ case 1: /* top */
1363+ *x = fgeom.borders.total.left + RESIZE_EXTENDS;
1364+ *y = 0;
1365+
1366+ if (d->frame_window)
1367+ *y += d->frame->win_extents.top + 2;
1368+
1369+ *w = width - fgeom.borders.total.left - fgeom.borders.total.right - (2 * RESIZE_EXTENDS);
1370+ *h = fgeom.borders.total.top - fgeom.title_rect.height;
1371+ break;
1372+ case 0: /* top left */
1373+ default:
1374+ *x = 0;
1375+ *y = 0;
1376+
1377+ if (d->frame_window)
1378+ {
1379+ *x += d->frame->win_extents.left + 4;
1380+ *y += d->frame->win_extents.top + 2 - fgeom.title_rect.height;
1381+ }
1382+
1383+ *w = fgeom.borders.total.left + RESIZE_EXTENDS;
1384+ *h = fgeom.borders.total.top + RESIZE_EXTENDS;
1385+ break;
1386+ }
1387+ break;
1388+ }
1389+
1390+ if (!(flags & META_FRAME_ALLOWS_VERTICAL_RESIZE))
1391+ {
1392+ /* turn off top and bottom event windows */
1393+ if (i == 0 || i == 2)
1394+ *w = *h = 0;
1395+ }
1396+
1397+ if (!(flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE))
1398+ {
1399+ /* turn off left and right event windows */
1400+ if (j == 0 || j == 2)
1401+ *w = *h = 0;
1402+ }
1403+}
1404+
1405+static MetaButtonFunction
1406+meta_button_function_from_string (const char *str)
1407+{
1408+ if (strcmp (str, "menu") == 0)
1409+ return META_BUTTON_FUNCTION_MENU;
1410+ else if (strcmp (str, "appmenu") == 0)
1411+ return META_BUTTON_FUNCTION_APPMENU;
1412+ else if (strcmp (str, "minimize") == 0)
1413+ return META_BUTTON_FUNCTION_MINIMIZE;
1414+ else if (strcmp (str, "maximize") == 0)
1415+ return META_BUTTON_FUNCTION_MAXIMIZE;
1416+ else if (strcmp (str, "close") == 0)
1417+ return META_BUTTON_FUNCTION_CLOSE;
1418+ else if (strcmp (str, "shade") == 0)
1419+ return META_BUTTON_FUNCTION_SHADE;
1420+ else if (strcmp (str, "above") == 0)
1421+ return META_BUTTON_FUNCTION_ABOVE;
1422+ else if (strcmp (str, "stick") == 0)
1423+ return META_BUTTON_FUNCTION_STICK;
1424+ else if (strcmp (str, "unshade") == 0)
1425+ return META_BUTTON_FUNCTION_UNSHADE;
1426+ else if (strcmp (str, "unabove") == 0)
1427+ return META_BUTTON_FUNCTION_UNABOVE;
1428+ else if (strcmp (str, "unstick") == 0)
1429+ return META_BUTTON_FUNCTION_UNSTICK;
1430+ else
1431+ return META_BUTTON_FUNCTION_LAST;
1432+}
1433+
1434+static MetaButtonFunction
1435+meta_button_opposite_function (MetaButtonFunction ofwhat)
1436+{
1437+ switch (ofwhat)
1438+ {
1439+ case META_BUTTON_FUNCTION_SHADE:
1440+ return META_BUTTON_FUNCTION_UNSHADE;
1441+ case META_BUTTON_FUNCTION_UNSHADE:
1442+ return META_BUTTON_FUNCTION_SHADE;
1443+
1444+ case META_BUTTON_FUNCTION_ABOVE:
1445+ return META_BUTTON_FUNCTION_UNABOVE;
1446+ case META_BUTTON_FUNCTION_UNABOVE:
1447+ return META_BUTTON_FUNCTION_ABOVE;
1448+
1449+ case META_BUTTON_FUNCTION_STICK:
1450+ return META_BUTTON_FUNCTION_UNSTICK;
1451+ case META_BUTTON_FUNCTION_UNSTICK:
1452+ return META_BUTTON_FUNCTION_STICK;
1453+
1454+ default:
1455+ return META_BUTTON_FUNCTION_LAST;
1456+ }
1457+}
1458+
1459+static void
1460+meta_initialize_button_layout (MetaButtonLayout *layout)
1461+{
1462+ int i;
1463+
1464+ for (i = 0; i < MAX_BUTTONS_PER_CORNER; ++i)
1465+ {
1466+ layout->left_buttons[i] = META_BUTTON_FUNCTION_LAST;
1467+ layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST;
1468+ layout->left_buttons_has_spacer[i] = FALSE;
1469+ layout->right_buttons_has_spacer[i] = FALSE;
1470+ }
1471+}
1472+
1473+void
1474+meta_update_button_layout (const char *value)
1475+{
1476+ MetaButtonLayout new_layout;
1477+ MetaButtonFunction f;
1478+ char **sides;
1479+ int i;
1480+
1481+ meta_initialize_button_layout (&new_layout);
1482+
1483+ sides = g_strsplit (value, ":", 2);
1484+
1485+ if (sides[0] != NULL)
1486+ {
1487+ char **buttons;
1488+ int b;
1489+ gboolean used[META_BUTTON_FUNCTION_LAST];
1490+
1491+ for (i = 0; i < META_BUTTON_FUNCTION_LAST; ++i)
1492+ used[i] = FALSE;
1493+
1494+ buttons = g_strsplit (sides[0], ",", -1);
1495+
1496+ i = b = 0;
1497+ while (buttons[b] != NULL)
1498+ {
1499+ f = meta_button_function_from_string (buttons[b]);
1500+ if (i > 0 && strcmp ("spacer", buttons[b]) == 0)
1501+ {
1502+ new_layout.left_buttons_has_spacer[i - 1] = TRUE;
1503+ f = meta_button_opposite_function (f);
1504+
1505+ if (f != META_BUTTON_FUNCTION_LAST)
1506+ new_layout.left_buttons_has_spacer[i - 2] = TRUE;
1507+ }
1508+ else
1509+ {
1510+ if (f != META_BUTTON_FUNCTION_LAST && !used[f])
1511+ {
1512+ used[f] = TRUE;
1513+ new_layout.left_buttons[i++] = f;
1514+
1515+ f = meta_button_opposite_function (f);
1516+
1517+ if (f != META_BUTTON_FUNCTION_LAST)
1518+ new_layout.left_buttons[i++] = f;
1519+
1520+ }
1521+ else
1522+ {
1523+ fprintf (stderr, "%s: Ignoring unknown or already-used "
1524+ "button name \"%s\"\n", program_name, buttons[b]);
1525+ }
1526+ }
1527+ ++b;
1528+ }
1529+
1530+ new_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
1531+
1532+ g_strfreev (buttons);
1533+
1534+ if (sides[1] != NULL)
1535+ {
1536+ for (i = 0; i < META_BUTTON_FUNCTION_LAST; ++i)
1537+ used[i] = FALSE;
1538+
1539+ buttons = g_strsplit (sides[1], ",", -1);
1540+
1541+ i = b = 0;
1542+ while (buttons[b] != NULL)
1543+ {
1544+ f = meta_button_function_from_string (buttons[b]);
1545+ if (i > 0 && strcmp ("spacer", buttons[b]) == 0)
1546+ {
1547+ new_layout.right_buttons_has_spacer[i - 1] = TRUE;
1548+ f = meta_button_opposite_function (f);
1549+ if (f != META_BUTTON_FUNCTION_LAST)
1550+ new_layout.right_buttons_has_spacer[i - 2] = TRUE;
1551+ }
1552+ else
1553+ {
1554+ if (f != META_BUTTON_FUNCTION_LAST && !used[f])
1555+ {
1556+ used[f] = TRUE;
1557+ new_layout.right_buttons[i++] = f;
1558+
1559+ f = meta_button_opposite_function (f);
1560+
1561+ if (f != META_BUTTON_FUNCTION_LAST)
1562+ new_layout.right_buttons[i++] = f;
1563+ }
1564+ else
1565+ {
1566+ fprintf (stderr, "%s: Ignoring unknown or "
1567+ "already-used button name \"%s\"\n",
1568+ program_name, buttons[b]);
1569+ }
1570+ }
1571+ ++b;
1572+ }
1573+
1574+ new_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
1575+
1576+ g_strfreev (buttons);
1577+ }
1578+ }
1579+
1580+ g_strfreev (sides);
1581+
1582+ /* Invert the button layout for RTL languages */
1583+ if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
1584+ {
1585+ MetaButtonLayout rtl_layout;
1586+ int j;
1587+
1588+ meta_initialize_button_layout (&rtl_layout);
1589+
1590+ i = 0;
1591+ while (new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST)
1592+ ++i;
1593+
1594+ for (j = 0; j < i; ++j)
1595+ {
1596+ rtl_layout.right_buttons[j] = new_layout.left_buttons[i - j - 1];
1597+ if (j == 0)
1598+ rtl_layout.right_buttons_has_spacer[i - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
1599+ else
1600+ rtl_layout.right_buttons_has_spacer[j - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
1601+ }
1602+
1603+ i = 0;
1604+ while (new_layout.right_buttons[i] != META_BUTTON_FUNCTION_LAST)
1605+ ++i;
1606+
1607+ for (j = 0; j < i; ++j)
1608+ {
1609+ rtl_layout.left_buttons[j] = new_layout.right_buttons[i - j - 1];
1610+ if (j == 0)
1611+ rtl_layout.left_buttons_has_spacer[i - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
1612+ else
1613+ rtl_layout.left_buttons_has_spacer[j - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
1614+ }
1615+
1616+ new_layout = rtl_layout;
1617+ }
1618+
1619+ meta_button_layout = new_layout;
1620+}
1621+
1622+void
1623+meta_update_border_extents (decor_frame_t *frame)
1624+{
1625+ MetaTheme *theme;
1626+ GdkScreen *screen;
1627+ MetaStyleInfo *style_info;
1628+ MetaFrameBorders borders;
1629+ MetaFrameType frame_type;
1630+ gint top_height;
1631+ gint bottom_height;
1632+ gint left_width;
1633+ gint right_width;
1634+
1635+ gwd_decor_frame_ref (frame);
1636+
1637+ frame_type = meta_frame_type_from_string (frame->type);
1638+ if (!(frame_type < META_FRAME_TYPE_LAST))
1639+ frame_type = META_FRAME_TYPE_NORMAL;
1640+
1641+ theme = meta_theme_get_current ();
1642+
1643+ screen = gtk_widget_get_screen (frame->style_window_rgba);
1644+ style_info = meta_theme_create_style_info (screen, NULL);
1645+
1646+ meta_theme_get_frame_borders (theme, style_info, frame_type, frame->text_height,
1647+ 0, &borders);
1648+
1649+ top_height = borders.visible.top;
1650+ bottom_height = borders.visible.bottom;
1651+ left_width = borders.visible.left;
1652+ right_width = borders.visible.right;
1653+
1654+ frame->win_extents.top = frame->win_extents.top;
1655+ frame->win_extents.bottom = bottom_height;
1656+ frame->win_extents.left = left_width;
1657+ frame->win_extents.right = right_width;
1658+
1659+ frame->titlebar_height = top_height - frame->win_extents.top;
1660+
1661+ meta_theme_get_frame_borders (theme, style_info, frame_type, frame->text_height,
1662+ META_FRAME_MAXIMIZED, &borders);
1663+
1664+ top_height = borders.visible.top;
1665+ bottom_height = borders.visible.bottom;
1666+ left_width = borders.visible.left;
1667+ right_width = borders.visible.right;
1668+
1669+ frame->max_win_extents.top = frame->win_extents.top;
1670+ frame->max_win_extents.bottom = bottom_height;
1671+ frame->max_win_extents.left = left_width;
1672+ frame->max_win_extents.right = right_width;
1673+
1674+ frame->max_titlebar_height = top_height - frame->max_win_extents.top;
1675+
1676+ meta_style_info_unref (style_info);
1677+
1678+ gwd_decor_frame_unref (frame);
1679+}
1680+
1681+#endif
1682
1683=== modified file 'plugins/grid/src/grid.cpp'
1684=== modified file 'plugins/opengl/src/paint.cpp'

Subscribers

People subscribed via source and target branches

to all changes: