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

Proposed by Marco Trevisan (Treviño)
Status: Superseded
Proposed branch: lp:~unity-team/compiz/x-sru6
Merge into: lp:compiz/0.9.13
Diff against target: 1727 lines (+1673/-1) (has conflicts)
5 files modified
VERSION (+4/-0)
debian/changelog (+108/-0)
gtk/window-decorator/decorator.c (+2/-0)
gtk/window-decorator/metacity.c.OTHER (+1555/-0)
src/region/src/region.cpp (+4/-1)
Text conflict in VERSION
Text conflict in debian/changelog
Contents conflict in gtk/window-decorator/metacity.c
To merge this branch: bzr merge lp:~unity-team/compiz/x-sru6
Reviewer Review Type Date Requested Status
Compiz Maintainers Pending
Review via email: mp+338344@code.launchpad.net

This proposal has been superseded by a proposal from 2018-02-20.

Commit message

Releasing Xenial Compiz SRU6

To post a comment you must log in.
lp:~unity-team/compiz/x-sru6 updated
4021. By Marco Trevisan (Treviño)

Region: define static const functions returning infinite and empty regions

See https://gcc.gnu.org/ml/gcc-help/2010-10/msg00255.html

Unmerged revisions

4021. By Marco Trevisan (Treviño)

Region: define static const functions returning infinite and empty regions

See https://gcc.gnu.org/ml/gcc-help/2010-10/msg00255.html

4020. By CI Train Bot Account

Releasing 1:0.9.12.3+16.04.20171116-0ubuntu1

4019. By CI Train Bot Account

* Added option to disable blend in grid plugin (LP: #1700859)
* Move: add options for showing only the window shape (filled or not)
  (LP: #1700859)
* Ensure that surfaces used by metacity theme have device scale set to
  1 . (LP: #1530277) (LP: #1530277)
* Use AnyPropertyType when getting _MOTIF_WM_HINTS property. (LP:
  #1702297)
* mate: Avoid artefacts of Windows Thumbnail Previews (LP: #1606369)
* move: damage all the border area in outline mode and ignore
  transparent colors (LP: #1700859)
* grid: ignore alpha in colors when not blending, and fix animations
  (LP: #1700859)
* resize: add support for disabling transparency and avoid over-
  damaging in outline mode (LP: #1700859)
* Screen: add averageColor to get the current desktop average color
* unity-lowgfx.ini: remove unsupported unity option

4018. By CI Train Bot Account

Releasing 1:0.9.12.2+16.04.20160823-0ubuntu1

4017. By CI Train Bot Account

[expo] limit scroll to workarea. (LP: #913880)

4016. By CI Train Bot Account

Releasing 1:0.9.12.2+16.04.20160801.3-0ubuntu1

4015. By CI Train Bot Account

* Don't activate expo if not needed (1x1 setup) (LP: #1606254)
* Don't crash if gsettings key is not found. Default value will be
  used. (LP: #1044662)
* focusDefaultWindow: focus Most Recently Used (MRU) window and
  fallback to the top window in case MRU list is not available. (LP:
  #1073488, LP: #1459671)
* Unity MigrationScript: sync gsettings on exit, and only use dconf on
  failure (LP: #1605011)

4014. By CI Train Bot Account

Releasing 1:0.9.12.2+16.04.20160714-0ubuntu1

4013. By CI Train Bot Account

* Added options for no animation in expo and scale plugins. They skip
  the intermediate fading steps that force several redraws.
* Added a new option in show desktop plugin that skips the fade
  animation: useful when performance is more important than eyecandy.
* debian: add unity-lowgfx profile to compizconfig (LP: #1598770)
* Composite: use C++ goodness for managing damaging rectangles
* ccsGSettingsBackend: don't try to update setting if wrapper is not
  found
* migration scripts: remove unsupported plugins for all the unity
  profiles

4012. By CI Train Bot Account

Releasing 1:0.9.12.2+16.04.20160526-0ubuntu1

Preview Diff

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

Subscribers

People subscribed via source and target branches

to all changes: