Compare commits
	
		
			47 Commits
		
	
	
		
			3.11.1
			...
			wip/mult-w
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 8b2a85f636 | ||
|   | df35234841 | ||
|   | 84b71cf297 | ||
|   | 8cf420b128 | ||
|   | d1dda65339 | ||
|   | 057d8830e9 | ||
|   | 570953819d | ||
|   | 0601987651 | ||
|   | 853098142f | ||
|   | 55180f5bb3 | ||
|   | 62b884dd42 | ||
|   | 3283018bfb | ||
|   | 55226ada8a | ||
|   | ff790f7b39 | ||
|   | 899570d213 | ||
|   | 3b2506851c | ||
|   | 9b88059e55 | ||
|   | 59168b2c64 | ||
|   | 47144253e4 | ||
|   | d8c66077f0 | ||
|   | 59a01137e1 | ||
|   | ce3804ee04 | ||
|   | f0bc53ce5a | ||
|   | b8938e9d4d | ||
|   | 7116d9cedb | ||
|   | 66fb86fd0c | ||
|   | 59cfbb07c8 | ||
|   | dc5bc3fea8 | ||
|   | fbbc32422e | ||
|   | fe8829f324 | ||
|   | b4036e061a | ||
|   | 4ee9f3563b | ||
|   | c652a54f59 | ||
|   | 61881477ac | ||
|   | 4373916d9d | ||
|   | 660d7df5ab | ||
|   | b7e3f627f1 | ||
|   | ca5d115715 | ||
|   | 21c46852cd | ||
|   | 10036832dd | ||
|   | 25b5ea8b4f | ||
|   | 20beaf7fe1 | ||
|   | e72af50420 | ||
|   | ef4417b717 | ||
|   | cf943627e2 | ||
|   | 96543cb009 | ||
|   | fbb2207f8c | 
							
								
								
									
										10
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								NEWS
									
									
									
									
									
								
							| @@ -1,9 +1,17 @@ | ||||
| 3.11.2 | ||||
| ====== | ||||
| * Fix resize operations using mouse-button-modifier [Lionel; #710251] | ||||
| * Misc. fixes and cleanups [Jasper, Rico, Florian; #711731] | ||||
|  | ||||
| Contributors: | ||||
|   Lionel Landwerlin, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz | ||||
|  | ||||
| 3.11.1 | ||||
| ====== | ||||
| * Don't require at least one output device to be connected [Giovanni; #709009] | ||||
| * Name the guard window [Andrew; #710346] | ||||
| * Use new UPower API [Bastien] | ||||
| * Expose min-backlight-stea [Asad; #710380] | ||||
| * Expose min-backlight-step [Asad; #710380] | ||||
| * Don't focus the no-focus-window for globally active windows [Jasper; #710296] | ||||
| * Misc. fixes and cleanups [Jasper, Rico, Olav, Magdalen; #709776] | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,7 @@ AC_CONFIG_MACRO_DIR([m4]) | ||||
|  | ||||
| m4_define([mutter_major_version], [3]) | ||||
| m4_define([mutter_minor_version], [11]) | ||||
| m4_define([mutter_micro_version], [1]) | ||||
| m4_define([mutter_micro_version], [2]) | ||||
|  | ||||
| m4_define([mutter_version], | ||||
|           [mutter_major_version.mutter_minor_version.mutter_micro_version]) | ||||
|   | ||||
| @@ -49,8 +49,8 @@ FIXXREF_OPTIONS= | ||||
| # Used for dependencies. The docs will be rebuilt if any of these change. | ||||
| # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h | ||||
| # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c | ||||
| HFILE_GLOB=$(top_srcdir)/src/*.h | ||||
| CFILE_GLOB=$(top_srcdir)/src/*.c | ||||
| HFILE_GLOB=$(top_srcdir)/src/*/*.h | ||||
| CFILE_GLOB=$(top_srcdir)/src/*/*.c | ||||
|  | ||||
| # Extra header to include when scanning, which are not under DOC_SOURCE_DIR | ||||
| # e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h | ||||
|   | ||||
| @@ -388,6 +388,23 @@ MetaWindowActorPrivate | ||||
| meta_window_actor_get_type | ||||
| </SECTION> | ||||
|  | ||||
| <SECTION> | ||||
| <FILE>meta-cullable</FILE> | ||||
| <TITLE>MetaCullable</TITLE> | ||||
| MetaCullable | ||||
| MetaCullableInterface | ||||
| meta_cullable_cull_out | ||||
| meta_cullable_reset_culling | ||||
| meta_cullable_cull_out_children | ||||
| meta_cullable_reset_culling_children | ||||
| <SUBSECTION Standard> | ||||
| META_TYPE_CULLABLE | ||||
| META_CULLABLE | ||||
| META_IS_CULLABLE | ||||
| META_CULLABLE_GET_IFACE | ||||
| meta_cullable_get_type | ||||
| </SECTION> | ||||
|  | ||||
| <SECTION> | ||||
| <FILE>prefs</FILE> | ||||
| MetaPreference | ||||
| @@ -541,7 +558,10 @@ meta_window_is_override_redirect | ||||
| meta_window_is_skip_taskbar | ||||
| meta_window_get_rect | ||||
| meta_window_get_input_rect | ||||
| meta_window_get_frame_rect | ||||
| meta_window_get_outer_rect | ||||
| meta_window_client_rect_to_frame_rect | ||||
| meta_window_frame_rect_to_client_rect | ||||
| meta_window_get_screen | ||||
| meta_window_get_display | ||||
| meta_window_get_xwindow | ||||
|   | ||||
| @@ -55,7 +55,8 @@ libmutter_la_SOURCES =				\ | ||||
| 	compositor/meta-background-actor.c	\ | ||||
| 	compositor/meta-background-actor-private.h	\ | ||||
| 	compositor/meta-background-group.c	\ | ||||
| 	compositor/meta-background-group-private.h	\ | ||||
| 	compositor/meta-cullable.c		\ | ||||
| 	compositor/meta-cullable.h		\ | ||||
| 	compositor/meta-module.c		\ | ||||
| 	compositor/meta-module.h		\ | ||||
| 	compositor/meta-plugin.c		\ | ||||
| @@ -168,7 +169,9 @@ libmutter_la_SOURCES =				\ | ||||
| 	ui/theme.c				\ | ||||
| 	meta/theme.h				\ | ||||
| 	ui/theme-private.h			\ | ||||
| 	ui/ui.c					\ | ||||
| 	ui/ui.c | ||||
|  | ||||
| nodist_libmutter_la_SOURCES =			\ | ||||
| 	$(mutter_built_sources) | ||||
|  | ||||
| libmutter_la_LDFLAGS = -no-undefined | ||||
| @@ -249,7 +252,7 @@ Meta-$(api_version).gir: libmutter.la | ||||
| @META_GIR@_FILES =				\ | ||||
| 	mutter-enum-types.h			\ | ||||
| 	$(libmutterinclude_base_headers)	\ | ||||
| 	$(filter %.c,$(libmutter_la_SOURCES)) | ||||
| 	$(filter %.c,$(libmutter_la_SOURCES) $(nodist_libmutter_la_SOURCES)) | ||||
| @META_GIR@_SCANNERFLAGS = --warn-all --warn-error | ||||
|  | ||||
| endif | ||||
|   | ||||
| @@ -150,10 +150,28 @@ add_win (MetaWindow *window) | ||||
| { | ||||
|   MetaScreen		*screen = meta_window_get_screen (window); | ||||
|   MetaCompScreen        *info = meta_screen_get_compositor_data (screen); | ||||
|   MetaWindowActor       *actor; | ||||
|   ClutterActor          *window_group; | ||||
|  | ||||
|   g_return_if_fail (info != NULL); | ||||
|  | ||||
|   meta_window_actor_new (window); | ||||
|   actor = meta_window_actor_new (window); | ||||
|  | ||||
|   window->core_actor = actor; | ||||
|  | ||||
|   if (window->layer == META_LAYER_OVERRIDE_REDIRECT) | ||||
|     window_group = info->top_window_group; | ||||
|   else | ||||
|     window_group = info->window_group; | ||||
|   clutter_actor_add_child (window_group, CLUTTER_ACTOR (actor)); | ||||
|  | ||||
|   clutter_actor_set_reactive (CLUTTER_ACTOR (actor), TRUE); | ||||
|   clutter_actor_hide (CLUTTER_ACTOR (actor)); | ||||
|  | ||||
|   /* Initial position in the stack is arbitrary; stacking will be synced | ||||
|    * before we first paint. | ||||
|    */ | ||||
|   info->windows = g_list_append (info->windows, actor); | ||||
|  | ||||
|   sync_actor_stacking (info); | ||||
| } | ||||
| @@ -163,16 +181,13 @@ process_damage (MetaCompositor     *compositor, | ||||
|                 XDamageNotifyEvent *event, | ||||
|                 MetaWindow         *window) | ||||
| { | ||||
|   MetaWindowActor *window_actor; | ||||
|   GSList *iter; | ||||
|  | ||||
|   if (window == NULL) | ||||
|     return; | ||||
|  | ||||
|   window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); | ||||
|   if (window_actor == NULL) | ||||
|     return; | ||||
|  | ||||
|   meta_window_actor_process_damage (window_actor, event); | ||||
|   for (iter = window->actors; iter != NULL; iter = iter->next) | ||||
|     meta_window_actor_process_damage (META_WINDOW_ACTOR (iter->data), event); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -180,24 +195,12 @@ process_property_notify (MetaCompositor	*compositor, | ||||
|                          XPropertyEvent *event, | ||||
|                          MetaWindow     *window) | ||||
| { | ||||
|   MetaWindowActor *window_actor; | ||||
|  | ||||
|   if (window == NULL) | ||||
|     return; | ||||
|  | ||||
|   window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); | ||||
|   if (window_actor == NULL) | ||||
|   if (window == NULL || window->core_actor == NULL) | ||||
|     return; | ||||
|  | ||||
|   /* Check for the opacity changing */ | ||||
|   if (event->atom == compositor->atom_net_wm_window_opacity) | ||||
|     { | ||||
|       meta_window_actor_update_opacity (window_actor); | ||||
|       DEBUG_TRACE ("process_property_notify: net_wm_window_opacity\n"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   DEBUG_TRACE ("process_property_notify: unknown\n"); | ||||
|     meta_window_actor_update_opacity (window->core_actor); | ||||
| } | ||||
|  | ||||
| static Window | ||||
| @@ -685,15 +688,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor, | ||||
|   clutter_actor_add_child (info->stage, info->window_group); | ||||
|   clutter_actor_add_child (info->stage, info->top_window_group); | ||||
|  | ||||
|   info->plugin_mgr = meta_plugin_manager_new (screen); | ||||
|  | ||||
|   /* | ||||
|    * Delay the creation of the overlay window as long as we can, to avoid | ||||
|    * blanking out the screen. This means that during the plugin loading, the | ||||
|    * overlay window is not accessible; if the plugin needs to access it | ||||
|    * directly, it should hook into the "show" signal on stage, and do | ||||
|    * its stuff there. | ||||
|    */ | ||||
|   info->output = get_output_window (screen); | ||||
|   XReparentWindow (xdisplay, xwin, info->output, 0, 0); | ||||
|  | ||||
| @@ -714,6 +708,8 @@ meta_compositor_manage_screen (MetaCompositor *compositor, | ||||
|       info->pending_input_region = None; | ||||
|     } | ||||
|  | ||||
|   info->plugin_mgr = meta_plugin_manager_new (screen); | ||||
|  | ||||
|   /* Map overlay window before redirecting windows offscreen so we catch their | ||||
|    * contents until we show the stage. | ||||
|    */ | ||||
| @@ -756,7 +752,7 @@ meta_shape_cow_for_window (MetaScreen *screen, | ||||
|       int width, height; | ||||
|       MetaRectangle rect; | ||||
|  | ||||
|       meta_window_get_outer_rect (metaWindow, &rect); | ||||
|       meta_window_get_frame_rect (metaWindow, &rect); | ||||
|  | ||||
|       window_bounds.x = rect.x; | ||||
|       window_bounds.y = rect.y; | ||||
| @@ -796,27 +792,30 @@ void | ||||
| meta_compositor_remove_window (MetaCompositor *compositor, | ||||
|                                MetaWindow     *window) | ||||
| { | ||||
|   MetaWindowActor         *window_actor     = NULL; | ||||
|   MetaScreen *screen; | ||||
|   MetaCompScreen *info; | ||||
|   GSList *iter; | ||||
|  | ||||
|   DEBUG_TRACE ("meta_compositor_remove_window\n"); | ||||
|   window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); | ||||
|   if (!window_actor) | ||||
|     return; | ||||
|  | ||||
|   screen = meta_window_get_screen (window); | ||||
|   info = meta_screen_get_compositor_data (screen); | ||||
|  | ||||
|   if (window_actor == info->unredirected_window) | ||||
|   if (window->core_actor == info->unredirected_window) | ||||
|     { | ||||
|       meta_window_actor_set_redirected (window_actor, TRUE); | ||||
|       meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)), | ||||
|                                  NULL); | ||||
|       meta_window_actor_set_redirected (info->unredirected_window, TRUE); | ||||
|       meta_shape_cow_for_window (meta_window_get_screen (window), NULL); | ||||
|       info->unredirected_window = NULL; | ||||
|     } | ||||
|  | ||||
|   meta_window_actor_destroy (window_actor); | ||||
|   window->core_actor = NULL; | ||||
|  | ||||
|   for (iter = window->actors; iter != NULL; iter = iter->next) | ||||
|     { | ||||
|       MetaWindowActor *actor = META_WINDOW_ACTOR (iter->data); | ||||
|       meta_window_actor_destroy (actor); | ||||
|       info->windows = g_list_remove (info->windows, (gconstpointer) actor); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -876,12 +875,10 @@ void | ||||
| meta_compositor_window_shape_changed (MetaCompositor *compositor, | ||||
|                                       MetaWindow     *window) | ||||
| { | ||||
|   MetaWindowActor *window_actor; | ||||
|   window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); | ||||
|   if (!window_actor) | ||||
|     return; | ||||
|   GSList *iter; | ||||
|  | ||||
|   meta_window_actor_update_shape (window_actor); | ||||
|   for (iter = window->actors; iter != NULL; iter = iter->next) | ||||
|     meta_window_actor_update_shape (META_WINDOW_ACTOR (iter->data)); | ||||
| } | ||||
|  | ||||
| /* Clutter makes the assumption that there is only one X window | ||||
| @@ -1044,12 +1041,8 @@ meta_compositor_show_window (MetaCompositor *compositor, | ||||
| 			     MetaWindow	    *window, | ||||
|                              MetaCompEffect  effect) | ||||
| { | ||||
|   MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); | ||||
|   DEBUG_TRACE ("meta_compositor_show_window\n"); | ||||
|   if (!window_actor) | ||||
|     return; | ||||
|  | ||||
|   meta_window_actor_show (window_actor, effect); | ||||
|   if (window->core_actor != NULL) | ||||
|     meta_window_actor_show (window->core_actor, effect); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -1057,12 +1050,8 @@ meta_compositor_hide_window (MetaCompositor *compositor, | ||||
|                              MetaWindow     *window, | ||||
|                              MetaCompEffect  effect) | ||||
| { | ||||
|   MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); | ||||
|   DEBUG_TRACE ("meta_compositor_hide_window\n"); | ||||
|   if (!window_actor) | ||||
|     return; | ||||
|  | ||||
|   meta_window_actor_hide (window_actor, effect); | ||||
|   if (window->core_actor != NULL) | ||||
|     meta_window_actor_hide (window->core_actor, effect); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -1071,12 +1060,8 @@ meta_compositor_maximize_window (MetaCompositor    *compositor, | ||||
| 				 MetaRectangle	   *old_rect, | ||||
| 				 MetaRectangle	   *new_rect) | ||||
| { | ||||
|   MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); | ||||
|   DEBUG_TRACE ("meta_compositor_maximize_window\n"); | ||||
|   if (!window_actor) | ||||
|     return; | ||||
|  | ||||
|   meta_window_actor_maximize (window_actor, old_rect, new_rect); | ||||
|   if (window->core_actor != NULL) | ||||
|     meta_window_actor_maximize (window->core_actor, old_rect, new_rect); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -1085,12 +1070,8 @@ meta_compositor_unmaximize_window (MetaCompositor    *compositor, | ||||
| 				   MetaRectangle     *old_rect, | ||||
| 				   MetaRectangle     *new_rect) | ||||
| { | ||||
|   MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); | ||||
|   DEBUG_TRACE ("meta_compositor_unmaximize_window\n"); | ||||
|   if (!window_actor) | ||||
|     return; | ||||
|  | ||||
|   meta_window_actor_unmaximize (window_actor, old_rect, new_rect); | ||||
|   if (window->core_actor != NULL) | ||||
|     meta_window_actor_unmaximize (window->core_actor, old_rect, new_rect); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -1266,7 +1247,7 @@ meta_compositor_sync_stack (MetaCompositor  *compositor, | ||||
|       while (stack) | ||||
|         { | ||||
|           stack_window = stack->data; | ||||
|           stack_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (stack_window)); | ||||
|           stack_actor = stack_window->core_actor; | ||||
|           if (!stack_actor) | ||||
|             { | ||||
|               meta_verbose ("Failed to find corresponding MetaWindowActor " | ||||
| @@ -1315,24 +1296,16 @@ void | ||||
| meta_compositor_window_mapped (MetaCompositor *compositor, | ||||
|                                MetaWindow     *window) | ||||
| { | ||||
|   MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); | ||||
|   DEBUG_TRACE ("meta_compositor_window_mapped\n"); | ||||
|   if (!window_actor) | ||||
|     return; | ||||
|  | ||||
|   meta_window_actor_mapped (window_actor); | ||||
|   if (window->core_actor != NULL) | ||||
|     meta_window_actor_mapped (window->core_actor); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_compositor_window_unmapped (MetaCompositor *compositor, | ||||
|                                  MetaWindow     *window) | ||||
| { | ||||
|   MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); | ||||
|   DEBUG_TRACE ("meta_compositor_window_unmapped\n"); | ||||
|   if (!window_actor) | ||||
|     return; | ||||
|  | ||||
|   meta_window_actor_unmapped (window_actor); | ||||
|   if (window->core_actor != NULL) | ||||
|     meta_window_actor_unmapped (window->core_actor); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -1340,17 +1313,8 @@ meta_compositor_sync_window_geometry (MetaCompositor *compositor, | ||||
| 				      MetaWindow *window, | ||||
|                                       gboolean did_placement) | ||||
| { | ||||
|   MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); | ||||
|   MetaScreen      *screen = meta_window_get_screen (window); | ||||
|   MetaCompScreen  *info = meta_screen_get_compositor_data (screen); | ||||
|  | ||||
|   DEBUG_TRACE ("meta_compositor_sync_window_geometry\n"); | ||||
|   g_return_if_fail (info); | ||||
|  | ||||
|   if (!window_actor) | ||||
|     return; | ||||
|  | ||||
|   meta_window_actor_sync_actor_geometry (window_actor, did_placement); | ||||
|   if (window->core_actor != NULL) | ||||
|     meta_window_actor_sync_actor_geometry (window->core_actor, did_placement); | ||||
| } | ||||
|  | ||||
| void | ||||
|   | ||||
| @@ -6,9 +6,6 @@ | ||||
| #include <meta/screen.h> | ||||
| #include <meta/meta-background-actor.h> | ||||
|  | ||||
| void meta_background_actor_set_clip_region  (MetaBackgroundActor *self, | ||||
|                                              cairo_region_t      *clip_region); | ||||
|  | ||||
| cairo_region_t *meta_background_actor_get_clip_region (MetaBackgroundActor *self); | ||||
|  | ||||
| #endif /* META_BACKGROUND_ACTOR_PRIVATE_H */ | ||||
|   | ||||
| @@ -41,20 +41,35 @@ | ||||
| #include <meta/errors.h> | ||||
| #include <meta/meta-background.h> | ||||
| #include "meta-background-actor-private.h" | ||||
| #include "meta-cullable.h" | ||||
|  | ||||
| struct _MetaBackgroundActorPrivate | ||||
| { | ||||
|   cairo_region_t *clip_region; | ||||
| }; | ||||
|  | ||||
| G_DEFINE_TYPE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR); | ||||
| static void cullable_iface_init (MetaCullableInterface *iface); | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_CODE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR, | ||||
|                          G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); | ||||
|  | ||||
| static void | ||||
| set_clip_region (MetaBackgroundActor *self, | ||||
|                  cairo_region_t      *clip_region) | ||||
| { | ||||
|   MetaBackgroundActorPrivate *priv = self->priv; | ||||
|  | ||||
|   g_clear_pointer (&priv->clip_region, (GDestroyNotify) cairo_region_destroy); | ||||
|   if (clip_region) | ||||
|     priv->clip_region = cairo_region_copy (clip_region); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_background_actor_dispose (GObject *object) | ||||
| { | ||||
|   MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object); | ||||
|  | ||||
|   meta_background_actor_set_clip_region (self, NULL); | ||||
|   set_clip_region (self, NULL); | ||||
|  | ||||
|   G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object); | ||||
| } | ||||
| @@ -104,26 +119,6 @@ meta_background_actor_get_preferred_height (ClutterActor *actor, | ||||
|     *natural_height_p = height; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_background_actor_get_paint_volume (ClutterActor       *actor, | ||||
|                                         ClutterPaintVolume *volume) | ||||
| { | ||||
|   ClutterContent *content; | ||||
|   gfloat width, height; | ||||
|  | ||||
|   content = clutter_actor_get_content (actor); | ||||
|  | ||||
|   if (!content) | ||||
|     return FALSE; | ||||
|  | ||||
|   clutter_content_get_preferred_size (content, &width, &height); | ||||
|  | ||||
|   clutter_paint_volume_set_width (volume, width); | ||||
|   clutter_paint_volume_set_height (volume, height); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_background_actor_class_init (MetaBackgroundActorClass *klass) | ||||
| { | ||||
| @@ -136,7 +131,6 @@ meta_background_actor_class_init (MetaBackgroundActorClass *klass) | ||||
|  | ||||
|   actor_class->get_preferred_width = meta_background_actor_get_preferred_width; | ||||
|   actor_class->get_preferred_height = meta_background_actor_get_preferred_height; | ||||
|   actor_class->get_paint_volume = meta_background_actor_get_paint_volume; | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -166,31 +160,27 @@ meta_background_actor_new (void) | ||||
|   return CLUTTER_ACTOR (self); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_background_actor_set_clip_region: | ||||
|  * @self: a #MetaBackgroundActor | ||||
|  * @clip_region: (allow-none): the area of the actor (in allocate-relative | ||||
|  *   coordinates) that is visible. | ||||
|  * | ||||
|  * Sets the area of the background that is unobscured by overlapping windows. | ||||
|  * This is used to optimize and only paint the visible portions. | ||||
|  */ | ||||
| void | ||||
| meta_background_actor_set_clip_region (MetaBackgroundActor *self, | ||||
|                                        cairo_region_t      *clip_region) | ||||
| static void | ||||
| meta_background_actor_cull_out (MetaCullable   *cullable, | ||||
|                                 cairo_region_t *unobscured_region, | ||||
|                                 cairo_region_t *clip_region) | ||||
| { | ||||
|   MetaBackgroundActorPrivate *priv; | ||||
|   MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable); | ||||
|   set_clip_region (self, clip_region); | ||||
| } | ||||
|  | ||||
|   g_return_if_fail (META_IS_BACKGROUND_ACTOR (self)); | ||||
| static void | ||||
| meta_background_actor_reset_culling (MetaCullable *cullable) | ||||
| { | ||||
|   MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable); | ||||
|   set_clip_region (self, NULL); | ||||
| } | ||||
|  | ||||
|   priv = self->priv; | ||||
|  | ||||
|   g_clear_pointer (&priv->clip_region, | ||||
|                    (GDestroyNotify) | ||||
|                    cairo_region_destroy); | ||||
|  | ||||
|   if (clip_region) | ||||
|     priv->clip_region = cairo_region_copy (clip_region); | ||||
| static void | ||||
| cullable_iface_init (MetaCullableInterface *iface) | ||||
| { | ||||
|   iface->cull_out = meta_background_actor_cull_out; | ||||
|   iface->reset_culling = meta_background_actor_reset_culling; | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -1,11 +0,0 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| #ifndef META_BACKGROUND_GROUP_PRIVATE_H | ||||
| #define META_BACKGROUND_GROUP_PRIVATE_H | ||||
|  | ||||
| #include <meta/screen.h> | ||||
| #include <meta/meta-background-group.h> | ||||
|  | ||||
| void meta_background_group_set_clip_region  (MetaBackgroundGroup *self, | ||||
|                                              cairo_region_t      *visible_region); | ||||
| #endif /* META_BACKGROUND_GROUP_PRIVATE_H */ | ||||
| @@ -16,87 +16,43 @@ | ||||
|  | ||||
| #include <config.h> | ||||
|  | ||||
| #include "compositor-private.h" | ||||
| #include "clutter-utils.h" | ||||
| #include "meta-background-actor-private.h" | ||||
| #include "meta-background-group-private.h" | ||||
| #include <meta/meta-background-group.h> | ||||
| #include "meta-cullable.h" | ||||
|  | ||||
| G_DEFINE_TYPE (MetaBackgroundGroup, meta_background_group, CLUTTER_TYPE_ACTOR); | ||||
| static void cullable_iface_init (MetaCullableInterface *iface); | ||||
|  | ||||
| struct _MetaBackgroundGroupPrivate | ||||
| { | ||||
|   gpointer dummy; | ||||
| }; | ||||
|  | ||||
| static void | ||||
| meta_background_group_dispose (GObject *object) | ||||
| { | ||||
|   G_OBJECT_CLASS (meta_background_group_parent_class)->dispose (object); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_background_group_get_paint_volume (ClutterActor       *actor, | ||||
|                                         ClutterPaintVolume *volume) | ||||
| { | ||||
|   return clutter_paint_volume_set_from_allocation (volume, actor); | ||||
| } | ||||
| G_DEFINE_TYPE_WITH_CODE (MetaBackgroundGroup, meta_background_group, CLUTTER_TYPE_ACTOR, | ||||
|                          G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); | ||||
|  | ||||
| static void | ||||
| meta_background_group_class_init (MetaBackgroundGroupClass *klass) | ||||
| { | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|   ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); | ||||
| } | ||||
|  | ||||
|   actor_class->get_paint_volume = meta_background_group_get_paint_volume; | ||||
|   object_class->dispose = meta_background_group_dispose; | ||||
| static void | ||||
| meta_background_group_cull_out (MetaCullable   *cullable, | ||||
|                                 cairo_region_t *unobscured_region, | ||||
|                                 cairo_region_t *clip_region) | ||||
| { | ||||
|   meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); | ||||
| } | ||||
|  | ||||
|   g_type_class_add_private (klass, sizeof (MetaBackgroundGroupPrivate)); | ||||
| static void | ||||
| meta_background_group_reset_culling (MetaCullable *cullable) | ||||
| { | ||||
|   meta_cullable_reset_culling_children (cullable); | ||||
| } | ||||
|  | ||||
| static void | ||||
| cullable_iface_init (MetaCullableInterface *iface) | ||||
| { | ||||
|   iface->cull_out = meta_background_group_cull_out; | ||||
|   iface->reset_culling = meta_background_group_reset_culling; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_background_group_init (MetaBackgroundGroup *self) | ||||
| { | ||||
|   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, | ||||
|                                             META_TYPE_BACKGROUND_GROUP, | ||||
|                                             MetaBackgroundGroupPrivate); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_background_group_set_clip_region: | ||||
|  * @self: a #MetaBackgroundGroup | ||||
|  * @region: (allow-none): the parts of the background to paint | ||||
|  * | ||||
|  * Sets the area of the backgrounds that is unobscured by overlapping windows. | ||||
|  * This is used to optimize and only paint the visible portions. | ||||
|  */ | ||||
| void | ||||
| meta_background_group_set_clip_region (MetaBackgroundGroup *self, | ||||
|                                        cairo_region_t      *region) | ||||
| { | ||||
|   GList *children, *l; | ||||
|  | ||||
|   children = clutter_actor_get_children (CLUTTER_ACTOR (self)); | ||||
|   for (l = children; l; l = l->next) | ||||
|     { | ||||
|       ClutterActor *actor = l->data; | ||||
|  | ||||
|       if (META_IS_BACKGROUND_ACTOR (actor)) | ||||
|         { | ||||
|           meta_background_actor_set_clip_region (META_BACKGROUND_ACTOR (actor), region); | ||||
|         } | ||||
|       else if (META_IS_BACKGROUND_GROUP (actor)) | ||||
|         { | ||||
|           int x, y; | ||||
|  | ||||
|           if (!meta_actor_is_untransformed (actor, &x, &y)) | ||||
|             continue; | ||||
|  | ||||
|           cairo_region_translate (region, -x, -y); | ||||
|           meta_background_group_set_clip_region (META_BACKGROUND_GROUP (actor), region); | ||||
|           cairo_region_translate (region, x, y); | ||||
|         } | ||||
|     } | ||||
|   g_list_free (children); | ||||
| } | ||||
|  | ||||
| ClutterActor * | ||||
|   | ||||
							
								
								
									
										191
									
								
								src/compositor/meta-cullable.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								src/compositor/meta-cullable.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,191 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
| /* | ||||
|  * Copyright (C) 2013 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Owen Taylor <otaylor@redhat.com> | ||||
|  *     Ray Strode <rstrode@redhat.com> | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
| #include "meta-cullable.h" | ||||
| #include "clutter-utils.h" | ||||
|  | ||||
| G_DEFINE_INTERFACE (MetaCullable, meta_cullable, CLUTTER_TYPE_ACTOR); | ||||
|  | ||||
| /** | ||||
|  * SECTION:meta-cullable | ||||
|  * @title: MetaCullable | ||||
|  * @short_description: CPU culling operations for efficient drawing | ||||
|  * | ||||
|  * When we are painting a stack of 5-10 large actors, the standard | ||||
|  * bottom-to-top method of drawing every actor results in a tremendous | ||||
|  * amount of overdraw. If these actors are painting textures like | ||||
|  * windows, it can easily max out the available memory bandwidth on a | ||||
|  * low-end graphics chipset. It's even worse if window textures are | ||||
|  * being accessed over the AGP bus. | ||||
|  * | ||||
|  * #MetaCullable is our solution. The basic technique applied here is to | ||||
|  * do a pre-pass before painting where we walk each actor from top to bottom | ||||
|  * and ask each actor to "cull itself out". We pass in a region it can copy | ||||
|  * to clip its drawing to, and the actor can subtract its fully opaque pixels | ||||
|  * so that actors underneath know not to draw there as well. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * meta_cullable_cull_out_children: | ||||
|  * @cullable: The #MetaCullable | ||||
|  * @unobscured_region: The unobscured region, as passed into cull_out() | ||||
|  * @clip_region: The clip region, as passed into cull_out() | ||||
|  * | ||||
|  * This is a helper method for actors that want to recurse over their | ||||
|  * child actors, and cull them out. | ||||
|  * | ||||
|  * See #MetaCullable and meta_cullable_cull_out() for more details. | ||||
|  */ | ||||
| void | ||||
| meta_cullable_cull_out_children (MetaCullable   *cullable, | ||||
|                                  cairo_region_t *unobscured_region, | ||||
|                                  cairo_region_t *clip_region) | ||||
| { | ||||
|   ClutterActor *actor = CLUTTER_ACTOR (cullable); | ||||
|   ClutterActor *child; | ||||
|   ClutterActorIter iter; | ||||
|  | ||||
|   clutter_actor_iter_init (&iter, actor); | ||||
|   while (clutter_actor_iter_prev (&iter, &child)) | ||||
|     { | ||||
|       int x, y; | ||||
|  | ||||
|       if (!CLUTTER_ACTOR_IS_VISIBLE (child)) | ||||
|         continue; | ||||
|  | ||||
|       /* If an actor has effects applied, then that can change the area | ||||
|        * it paints and the opacity, so we no longer can figure out what | ||||
|        * portion of the actor is obscured and what portion of the screen | ||||
|        * it obscures, so we skip the actor. | ||||
|        * | ||||
|        * This has a secondary beneficial effect: if a ClutterOffscreenEffect | ||||
|        * is applied to an actor, then our clipped redraws interfere with the | ||||
|        * caching of the FBO - even if we only need to draw a small portion | ||||
|        * of the window right now, ClutterOffscreenEffect may use other portions | ||||
|        * of the FBO later. So, skipping actors with effects applied also | ||||
|        * prevents these bugs. | ||||
|        * | ||||
|        * Theoretically, we should check clutter_actor_get_offscreen_redirect() | ||||
|        * as well for the same reason, but omitted for simplicity in the | ||||
|        * hopes that no-one will do that. | ||||
|        */ | ||||
|       if (clutter_actor_has_effects (child)) | ||||
|         continue; | ||||
|  | ||||
|       if (!META_IS_CULLABLE (child)) | ||||
|         continue; | ||||
|  | ||||
|       if (!meta_actor_is_untransformed (child, &x, &y)) | ||||
|         continue; | ||||
|  | ||||
|       /* Temporarily move to the coordinate system of the actor */ | ||||
|       cairo_region_translate (unobscured_region, - x, - y); | ||||
|       cairo_region_translate (clip_region, - x, - y); | ||||
|  | ||||
|       meta_cullable_cull_out (META_CULLABLE (child), unobscured_region, clip_region); | ||||
|  | ||||
|       cairo_region_translate (unobscured_region, x, y); | ||||
|       cairo_region_translate (clip_region, x, y); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_cullable_reset_culling_children: | ||||
|  * @cullable: The #MetaCullable | ||||
|  * | ||||
|  * This is a helper method for actors that want to recurse over their | ||||
|  * child actors, and cull them out. | ||||
|  * | ||||
|  * See #MetaCullable and meta_cullable_reset_culling() for more details. | ||||
|  */ | ||||
| void | ||||
| meta_cullable_reset_culling_children (MetaCullable *cullable) | ||||
| { | ||||
|   ClutterActor *actor = CLUTTER_ACTOR (cullable); | ||||
|   ClutterActor *child; | ||||
|   ClutterActorIter iter; | ||||
|  | ||||
|   clutter_actor_iter_init (&iter, actor); | ||||
|   while (clutter_actor_iter_next (&iter, &child)) | ||||
|     { | ||||
|       if (!META_IS_CULLABLE (child)) | ||||
|         continue; | ||||
|  | ||||
|       meta_cullable_reset_culling (META_CULLABLE (child)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_cullable_default_init (MetaCullableInterface *iface) | ||||
| { | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_cullable_cull_out: | ||||
|  * @cullable: The #MetaCullable | ||||
|  * @unobscured_region: The unobscured region, in @cullable's space. | ||||
|  * @clip_region: The clip region, in @cullable's space. | ||||
|  * | ||||
|  * When #MetaWindowGroup is painted, we walk over its direct cullable | ||||
|  * children from top to bottom and ask themselves to "cull out". Cullables | ||||
|  * can use @unobscured_region and @clip_region to clip their drawing. Actors | ||||
|  * interested in eliminating overdraw should copy the @clip_region and only | ||||
|  * paint those parts, as everything else has been obscured by actors above it. | ||||
|  * | ||||
|  * Actors that may have fully opaque parts should also subtract out a region | ||||
|  * that is fully opaque from @unobscured_region and @clip_region. | ||||
|  * | ||||
|  * @unobscured_region and @clip_region are extremely similar. The difference | ||||
|  * is that @clip_region starts off with the stage's clip, if Clutter detects | ||||
|  * that we're doing a clipped redraw. @unobscured_region, however, starts off | ||||
|  * with the full stage size, so actors that may want to record what parts of | ||||
|  * their window are unobscured for e.g. scheduling repaints can do so. | ||||
|  * | ||||
|  * Actors that have children can also use the meta_cullable_cull_out_children() | ||||
|  * helper method to do a simple cull across all their children. | ||||
|  */ | ||||
| void | ||||
| meta_cullable_cull_out (MetaCullable   *cullable, | ||||
|                         cairo_region_t *unobscured_region, | ||||
|                         cairo_region_t *clip_region) | ||||
| { | ||||
|   META_CULLABLE_GET_IFACE (cullable)->cull_out (cullable, unobscured_region, clip_region); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_cullable_reset_culling: | ||||
|  * @cullable: The #MetaCullable | ||||
|  * | ||||
|  * Actors that copied data in their cull_out() implementation can now | ||||
|  * reset their data, as the paint is now over. Additional paints may be | ||||
|  * done by #ClutterClone or similar, and they should not be affected by | ||||
|  * the culling operation. | ||||
|  */ | ||||
| void | ||||
| meta_cullable_reset_culling (MetaCullable *cullable) | ||||
| { | ||||
|   META_CULLABLE_GET_IFACE (cullable)->reset_culling (cullable); | ||||
| } | ||||
							
								
								
									
										68
									
								
								src/compositor/meta-cullable.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/compositor/meta-cullable.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2013 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Owen Taylor <otaylor@redhat.com> | ||||
|  *     Ray Strode <rstrode@redhat.com> | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
| #ifndef __META_CULLABLE_H__ | ||||
| #define __META_CULLABLE_H__ | ||||
|  | ||||
| #include <clutter/clutter.h> | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define META_TYPE_CULLABLE             (meta_cullable_get_type ()) | ||||
| #define META_CULLABLE(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CULLABLE, MetaCullable)) | ||||
| #define META_IS_CULLABLE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CULLABLE)) | ||||
| #define META_CULLABLE_GET_IFACE(obj)   (G_TYPE_INSTANCE_GET_INTERFACE ((obj),  META_TYPE_CULLABLE, MetaCullableInterface)) | ||||
|  | ||||
| typedef struct _MetaCullable MetaCullable; | ||||
| typedef struct _MetaCullableInterface MetaCullableInterface; | ||||
|  | ||||
| struct _MetaCullableInterface | ||||
| { | ||||
|   GTypeInterface g_iface; | ||||
|  | ||||
|   void (* cull_out)      (MetaCullable   *cullable, | ||||
|                           cairo_region_t *unobscured_region, | ||||
|                           cairo_region_t *clip_region); | ||||
|   void (* reset_culling) (MetaCullable  *cullable); | ||||
| }; | ||||
|  | ||||
| GType meta_cullable_get_type (void); | ||||
|  | ||||
| void meta_cullable_cull_out (MetaCullable   *cullable, | ||||
|                              cairo_region_t *unobscured_region, | ||||
|                              cairo_region_t *clip_region); | ||||
| void meta_cullable_reset_culling (MetaCullable *cullable); | ||||
|  | ||||
| /* Utility methods for implementations */ | ||||
| void meta_cullable_cull_out_children (MetaCullable   *cullable, | ||||
|                                       cairo_region_t *unobscured_region, | ||||
|                                       cairo_region_t *clip_region); | ||||
| void meta_cullable_reset_culling_children (MetaCullable *cullable); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* __META_CULLABLE_H__ */ | ||||
|  | ||||
| @@ -72,6 +72,7 @@ struct _MetaShapedTexturePrivate | ||||
|  | ||||
|   cairo_region_t *clip_region; | ||||
|   cairo_region_t *opaque_region; | ||||
|   cairo_region_t *input_shape_region; | ||||
|  | ||||
|   guint tex_width, tex_height; | ||||
|  | ||||
| @@ -394,45 +395,60 @@ meta_shaped_texture_pick (ClutterActor       *actor, | ||||
|   MetaShapedTexture *stex = (MetaShapedTexture *) actor; | ||||
|   MetaShapedTexturePrivate *priv = stex->priv; | ||||
|  | ||||
|   if (!clutter_actor_should_pick_paint (actor) || | ||||
|       (priv->clip_region && cairo_region_is_empty (priv->clip_region))) | ||||
|     return; | ||||
|  | ||||
|   /* If there is no region then use the regular pick */ | ||||
|   if (priv->mask_texture == NULL) | ||||
|   if (priv->input_shape_region == NULL) | ||||
|     CLUTTER_ACTOR_CLASS (meta_shaped_texture_parent_class)->pick (actor, color); | ||||
|   else if (clutter_actor_should_pick_paint (actor)) | ||||
|   else | ||||
|     { | ||||
|       CoglTexture *paint_tex; | ||||
|       ClutterActorBox alloc; | ||||
|       guint tex_width, tex_height; | ||||
|       int n_rects; | ||||
|       float *rectangles; | ||||
|       int i; | ||||
|       CoglPipeline *pipeline; | ||||
|       CoglContext *ctx; | ||||
|       CoglFramebuffer *fb; | ||||
|       CoglColor cogl_color; | ||||
|  | ||||
|       paint_tex = COGL_TEXTURE (priv->texture); | ||||
|       /* Note: We don't bother trying to intersect the pick and clip regions | ||||
|        * since needing to copy the region, do the intersection, and probably | ||||
|        * increase the number of rectangles seems more likely to have a negative | ||||
|        * effect. | ||||
|        * | ||||
|        * NB: Most of the time when just using rectangles for picking then | ||||
|        * picking shouldn't involve any rendering, and minimizing the number of | ||||
|        * rectangles has more benefit than reducing the area of the pick | ||||
|        * region. | ||||
|        */ | ||||
|  | ||||
|       if (paint_tex == NULL) | ||||
|         return; | ||||
|       n_rects = cairo_region_num_rectangles (priv->input_shape_region); | ||||
|       rectangles = g_alloca (sizeof (float) * 4 * n_rects); | ||||
|  | ||||
|       tex_width = cogl_texture_get_width (paint_tex); | ||||
|       tex_height = cogl_texture_get_height (paint_tex); | ||||
|       for (i = 0; i < n_rects; i++) | ||||
|         { | ||||
|           cairo_rectangle_int_t rect; | ||||
|           int pos = i * 4; | ||||
|  | ||||
|       if (tex_width == 0 || tex_height == 0) /* no contents yet */ | ||||
|         return; | ||||
|           cairo_region_get_rectangle (priv->input_shape_region, i, &rect); | ||||
|  | ||||
|           rectangles[pos] = rect.x; | ||||
|           rectangles[pos + 1] = rect.y; | ||||
|           rectangles[pos + 2] = rect.x + rect.width; | ||||
|           rectangles[pos + 3] = rect.y + rect.height; | ||||
|         } | ||||
|  | ||||
|       ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); | ||||
|       fb = cogl_get_draw_framebuffer (); | ||||
|  | ||||
|       cogl_color_init_from_4ub (&cogl_color, color->red, color->green, color->blue, color->alpha); | ||||
|  | ||||
|       pipeline = get_masked_pipeline (ctx); | ||||
|       cogl_pipeline_set_layer_texture (pipeline, 1, priv->mask_texture); | ||||
|       pipeline = cogl_pipeline_new (ctx); | ||||
|       cogl_pipeline_set_color (pipeline, &cogl_color); | ||||
|  | ||||
|       clutter_actor_get_allocation_box (actor, &alloc); | ||||
|  | ||||
|       cogl_framebuffer_draw_rectangle (fb, pipeline, | ||||
|                                        0, 0, | ||||
|                                        alloc.x2 - alloc.x1, | ||||
|                                        alloc.y2 - alloc.y1); | ||||
|       cogl_framebuffer_draw_rectangles (fb, pipeline, | ||||
|                                         rectangles, n_rects); | ||||
|       cogl_object_unref (pipeline); | ||||
|     } | ||||
| } | ||||
| @@ -691,6 +707,41 @@ meta_shaped_texture_get_texture (MetaShapedTexture *stex) | ||||
|   return COGL_TEXTURE (stex->priv->texture); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_shaped_texture_set_input_shape_region: | ||||
|  * @stex: a #MetaShapedTexture | ||||
|  * @shape_region: the region of the texture that should respond to | ||||
|  *    input. | ||||
|  * | ||||
|  * Determines what region of the texture should accept input. For | ||||
|  * X based windows this is defined by the ShapeInput region of the | ||||
|  * window. | ||||
|  */ | ||||
| void | ||||
| meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex, | ||||
|                                             cairo_region_t    *shape_region) | ||||
| { | ||||
|   MetaShapedTexturePrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); | ||||
|  | ||||
|   priv = stex->priv; | ||||
|  | ||||
|   if (priv->input_shape_region != NULL) | ||||
|     { | ||||
|       cairo_region_destroy (priv->input_shape_region); | ||||
|       priv->input_shape_region = NULL; | ||||
|     } | ||||
|  | ||||
|   if (shape_region != NULL) | ||||
|     { | ||||
|       cairo_region_reference (shape_region); | ||||
|       priv->input_shape_region = shape_region; | ||||
|     } | ||||
|  | ||||
|   clutter_actor_queue_redraw (CLUTTER_ACTOR (stex)); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_shaped_texture_set_clip_region: | ||||
|  * @stex: a #MetaShapedTexture | ||||
|   | ||||
| @@ -55,14 +55,6 @@ void     meta_window_actor_set_updates_frozen  (MetaWindowActor *self, | ||||
| void     meta_window_actor_queue_frame_drawn   (MetaWindowActor *self, | ||||
|                                                 gboolean         no_delay_frame); | ||||
|  | ||||
| cairo_region_t *meta_window_actor_get_obscured_region (MetaWindowActor *self); | ||||
|  | ||||
| void meta_window_actor_set_clip_region         (MetaWindowActor *self, | ||||
|                                                 cairo_region_t  *clip_region); | ||||
| void meta_window_actor_set_clip_region_beneath (MetaWindowActor *self, | ||||
|                                                 cairo_region_t  *beneath_region); | ||||
| void meta_window_actor_reset_clip_regions      (MetaWindowActor *self); | ||||
|  | ||||
| void meta_window_actor_set_unobscured_region      (MetaWindowActor *self, | ||||
|                                                    cairo_region_t  *unobscured_region); | ||||
|  | ||||
|   | ||||
| @@ -32,20 +32,13 @@ | ||||
| #include "meta-texture-rectangle.h" | ||||
| #include "region-utils.h" | ||||
| #include "monitor-private.h" | ||||
| #include "meta-cullable.h" | ||||
|  | ||||
| enum { | ||||
|   POSITION_CHANGED, | ||||
|   SIZE_CHANGED, | ||||
|   LAST_SIGNAL | ||||
| }; | ||||
|  | ||||
| static guint signals[LAST_SIGNAL] = {0}; | ||||
|  | ||||
| static void meta_window_actor_queue_create_pixmap (MetaWindowActor *self); | ||||
|  | ||||
| struct _MetaWindowActorPrivate | ||||
| { | ||||
|   MetaWindow       *window; | ||||
|   Window            xwindow; | ||||
|   MetaScreen       *screen; | ||||
|  | ||||
|   ClutterActor     *actor; | ||||
| @@ -72,6 +65,8 @@ struct _MetaWindowActorPrivate | ||||
|  | ||||
|   /* A region that matches the shape of the window, including frame bounds */ | ||||
|   cairo_region_t   *shape_region; | ||||
|   /* If the window has an input shape, a region that matches the shape */ | ||||
|   cairo_region_t   *input_region; | ||||
|   /* The opaque region, from _NET_WM_OPAQUE_REGION, intersected with | ||||
|    * the shape region. */ | ||||
|   cairo_region_t   *opaque_region; | ||||
| @@ -152,8 +147,6 @@ struct _FrameData | ||||
| enum | ||||
| { | ||||
|   PROP_META_WINDOW = 1, | ||||
|   PROP_META_SCREEN, | ||||
|   PROP_X_WINDOW, | ||||
|   PROP_NO_SHADOW, | ||||
|   PROP_SHADOW_CLASS | ||||
| }; | ||||
| @@ -189,7 +182,10 @@ static void do_send_frame_timings (MetaWindowActor  *self, | ||||
|                                    gint             refresh_interval, | ||||
|                                    gint64           presentation_time); | ||||
|  | ||||
| G_DEFINE_TYPE (MetaWindowActor, meta_window_actor, CLUTTER_TYPE_ACTOR); | ||||
| static void cullable_iface_init (MetaCullableInterface *iface); | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_CODE (MetaWindowActor, meta_window_actor, CLUTTER_TYPE_ACTOR, | ||||
|                          G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); | ||||
|  | ||||
| static void | ||||
| frame_data_free (FrameData *frame) | ||||
| @@ -219,33 +215,12 @@ meta_window_actor_class_init (MetaWindowActorClass *klass) | ||||
|                                "MetaWindow", | ||||
|                                "The displayed MetaWindow", | ||||
|                                META_TYPE_WINDOW, | ||||
|                                G_PARAM_READWRITE | G_PARAM_CONSTRUCT); | ||||
|                                G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); | ||||
|  | ||||
|   g_object_class_install_property (object_class, | ||||
|                                    PROP_META_WINDOW, | ||||
|                                    pspec); | ||||
|  | ||||
|   pspec = g_param_spec_pointer ("meta-screen", | ||||
| 				"MetaScreen", | ||||
| 				"MetaScreen", | ||||
| 				G_PARAM_READWRITE | G_PARAM_CONSTRUCT); | ||||
|  | ||||
|   g_object_class_install_property (object_class, | ||||
|                                    PROP_META_SCREEN, | ||||
|                                    pspec); | ||||
|  | ||||
|   pspec = g_param_spec_ulong ("x-window", | ||||
| 			      "Window", | ||||
| 			      "Window", | ||||
| 			      0, | ||||
| 			      G_MAXULONG, | ||||
| 			      0, | ||||
| 			      G_PARAM_READWRITE | G_PARAM_CONSTRUCT); | ||||
|  | ||||
|   g_object_class_install_property (object_class, | ||||
|                                    PROP_X_WINDOW, | ||||
|                                    pspec); | ||||
|  | ||||
|   pspec = g_param_spec_boolean ("no-shadow", | ||||
|                                 "No shadow", | ||||
|                                 "Do not add shaddow to this window", | ||||
| @@ -265,19 +240,6 @@ meta_window_actor_class_init (MetaWindowActorClass *klass) | ||||
|   g_object_class_install_property (object_class, | ||||
|                                    PROP_SHADOW_CLASS, | ||||
|                                    pspec); | ||||
|  | ||||
|   signals[POSITION_CHANGED] = | ||||
|     g_signal_new ("position-changed", | ||||
|                   G_TYPE_FROM_CLASS (klass), | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   0, NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 0); | ||||
|   signals[SIZE_CHANGED] = | ||||
|     g_signal_new ("size-changed", | ||||
|                   G_TYPE_FROM_CLASS (klass), | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   0, NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 0); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -290,6 +252,9 @@ meta_window_actor_init (MetaWindowActor *self) | ||||
| 						   MetaWindowActorPrivate); | ||||
|   priv->opacity = 0xff; | ||||
|   priv->shadow_class = NULL; | ||||
|  | ||||
|   priv->last_width = -1; | ||||
|   priv->last_height = -1; | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -299,11 +264,9 @@ window_decorated_notify (MetaWindow *mw, | ||||
| { | ||||
|   MetaWindowActor        *self     = META_WINDOW_ACTOR (data); | ||||
|   MetaWindowActorPrivate *priv     = self->priv; | ||||
|   MetaFrame              *frame    = meta_window_get_frame (mw); | ||||
|   MetaScreen             *screen   = priv->screen; | ||||
|   MetaDisplay            *display  = meta_screen_get_display (screen); | ||||
|   Display                *xdisplay = meta_display_get_xdisplay (display); | ||||
|   Window                  new_xwindow; | ||||
|  | ||||
|   /* | ||||
|    * Basically, we have to reconstruct the the internals of this object | ||||
| @@ -311,11 +274,6 @@ window_decorated_notify (MetaWindow *mw, | ||||
|    */ | ||||
|   priv->redecorating = TRUE; | ||||
|  | ||||
|   if (frame) | ||||
|     new_xwindow = meta_frame_get_xwindow (frame); | ||||
|   else | ||||
|     new_xwindow = meta_window_get_xwindow (mw); | ||||
|  | ||||
|   meta_window_actor_detach (self); | ||||
|  | ||||
|   /* | ||||
| @@ -330,7 +288,7 @@ window_decorated_notify (MetaWindow *mw, | ||||
|       priv->damage = None; | ||||
|     } | ||||
|  | ||||
|   priv->xwindow = new_xwindow; | ||||
|   priv->xwindow = meta_window_get_toplevel_xwindow (priv->window); | ||||
|  | ||||
|   /* | ||||
|    * Recreate the contents. | ||||
| @@ -351,13 +309,16 @@ meta_window_actor_constructed (GObject *object) | ||||
| { | ||||
|   MetaWindowActor        *self     = META_WINDOW_ACTOR (object); | ||||
|   MetaWindowActorPrivate *priv     = self->priv; | ||||
|   MetaScreen             *screen   = priv->screen; | ||||
|   MetaDisplay            *display  = meta_screen_get_display (screen); | ||||
|   Window                  xwindow  = priv->xwindow; | ||||
|   MetaWindow             *window   = priv->window; | ||||
|   MetaScreen             *screen   = meta_window_get_screen (window); | ||||
|   MetaDisplay            *display  = meta_screen_get_display (screen); | ||||
|   Display                *xdisplay = meta_display_get_xdisplay (display); | ||||
|   XRenderPictFormat      *format; | ||||
|   Window                  xwindow; | ||||
|  | ||||
|   xwindow = meta_window_get_toplevel_xwindow (window); | ||||
|  | ||||
|   priv->screen = screen; | ||||
|   priv->damage = XDamageCreate (xdisplay, xwindow, | ||||
|                                 XDamageReportBoundingBox); | ||||
|  | ||||
| @@ -386,20 +347,28 @@ meta_window_actor_constructed (GObject *object) | ||||
|       g_signal_connect_object (window, "notify::appears-focused", | ||||
|                                G_CALLBACK (window_appears_focused_notify), self, 0); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* | ||||
|        * This is the case where existing window is gaining/loosing frame. | ||||
|        * Just ensure the actor is top most (i.e., above shadow). | ||||
|        */ | ||||
|       clutter_actor_set_child_above_sibling (CLUTTER_ACTOR (self), priv->actor, NULL); | ||||
|     } | ||||
|  | ||||
|   meta_window_actor_update_opacity (self); | ||||
|   meta_window_actor_sync_actor_position (self); | ||||
|  | ||||
|   priv->mapped = meta_window_toplevel_is_mapped (priv->window); | ||||
|   if (priv->mapped) | ||||
|     meta_window_actor_queue_create_pixmap (self); | ||||
|  | ||||
|   meta_window_actor_set_updates_frozen (self, | ||||
|                                         meta_window_updates_are_frozen (priv->window)); | ||||
|  | ||||
|   /* If a window doesn't start off with updates frozen, we should | ||||
|    * we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn. | ||||
|    */ | ||||
|   if (priv->window->extended_sync_request_counter && !priv->updates_frozen) | ||||
|     meta_window_actor_queue_frame_drawn (self, FALSE); | ||||
|  | ||||
|   /* Start off with an empty region to maintain the invariant that | ||||
|      the shape region is always set */ | ||||
|   priv->shape_region = cairo_region_create (); | ||||
|  | ||||
|   G_OBJECT_CLASS (meta_window_actor_parent_class)->constructed (object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -410,7 +379,6 @@ meta_window_actor_dispose (GObject *object) | ||||
|   MetaScreen             *screen; | ||||
|   MetaDisplay            *display; | ||||
|   Display                *xdisplay; | ||||
|   MetaCompScreen         *info; | ||||
|  | ||||
|   if (priv->disposed) | ||||
|     return; | ||||
| @@ -420,7 +388,6 @@ meta_window_actor_dispose (GObject *object) | ||||
|   screen   = priv->screen; | ||||
|   display  = meta_screen_get_display (screen); | ||||
|   xdisplay = meta_display_get_xdisplay (display); | ||||
|   info     = meta_screen_get_compositor_data (screen); | ||||
|  | ||||
|   meta_window_actor_detach (self); | ||||
|  | ||||
| @@ -432,6 +399,7 @@ meta_window_actor_dispose (GObject *object) | ||||
|  | ||||
|   g_clear_pointer (&priv->unobscured_region, cairo_region_destroy); | ||||
|   g_clear_pointer (&priv->shape_region, cairo_region_destroy); | ||||
|   g_clear_pointer (&priv->input_region, cairo_region_destroy); | ||||
|   g_clear_pointer (&priv->opaque_region, cairo_region_destroy); | ||||
|   g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); | ||||
|  | ||||
| @@ -449,8 +417,6 @@ meta_window_actor_dispose (GObject *object) | ||||
|       priv->damage = None; | ||||
|     } | ||||
|  | ||||
|   info->windows = g_list_remove (info->windows, (gconstpointer) self); | ||||
|  | ||||
|   g_clear_object (&priv->window); | ||||
|  | ||||
|   /* | ||||
| @@ -484,17 +450,7 @@ meta_window_actor_set_property (GObject      *object, | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_META_WINDOW: | ||||
|       { | ||||
|         if (priv->window) | ||||
|           g_object_unref (priv->window); | ||||
|         priv->window = g_value_dup_object (value); | ||||
|       } | ||||
|       break; | ||||
|     case PROP_META_SCREEN: | ||||
|       priv->screen = g_value_get_pointer (value); | ||||
|       break; | ||||
|     case PROP_X_WINDOW: | ||||
|       priv->xwindow = g_value_get_ulong (value); | ||||
|       priv->window = g_value_dup_object (value); | ||||
|       break; | ||||
|     case PROP_NO_SHADOW: | ||||
|       { | ||||
| @@ -540,12 +496,6 @@ meta_window_actor_get_property (GObject      *object, | ||||
|     case PROP_META_WINDOW: | ||||
|       g_value_set_object (value, priv->window); | ||||
|       break; | ||||
|     case PROP_META_SCREEN: | ||||
|       g_value_set_pointer (value, priv->screen); | ||||
|       break; | ||||
|     case PROP_X_WINDOW: | ||||
|       g_value_set_ulong (value, priv->xwindow); | ||||
|       break; | ||||
|     case PROP_NO_SHADOW: | ||||
|       g_value_set_boolean (value, priv->no_shadow); | ||||
|       break; | ||||
| @@ -813,20 +763,6 @@ meta_window_actor_has_shadow (MetaWindowActor *self) | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_window_actor_get_x_window: (skip) | ||||
|  * @self: a #MetaWindowActor | ||||
|  * | ||||
|  */ | ||||
| Window | ||||
| meta_window_actor_get_x_window (MetaWindowActor *self) | ||||
| { | ||||
|   if (!self) | ||||
|     return None; | ||||
|  | ||||
|   return self->priv->xwindow; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_window_actor_get_meta_window: | ||||
|  * @self: a #MetaWindowActor | ||||
| @@ -869,59 +805,6 @@ meta_window_actor_is_destroyed (MetaWindowActor *self) | ||||
|   return self->priv->disposed; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_window_actor_is_override_redirect (MetaWindowActor *self) | ||||
| { | ||||
|   return meta_window_is_override_redirect (self->priv->window); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_window_actor_get_workspace: | ||||
|  * @self: #MetaWindowActor | ||||
|  * | ||||
|  * Returns the index of workspace on which this window is located; if the | ||||
|  * window is sticky, or is not currently located on any workspace, returns -1. | ||||
|  * This function is deprecated  and should not be used in newly written code; | ||||
|  * meta_window_get_workspace() instead. | ||||
|  * | ||||
|  * Return value: (transfer none): index of workspace on which this window is | ||||
|  * located. | ||||
|  */ | ||||
| gint | ||||
| meta_window_actor_get_workspace (MetaWindowActor *self) | ||||
| { | ||||
|   MetaWindowActorPrivate *priv; | ||||
|   MetaWorkspace          *workspace; | ||||
|  | ||||
|   if (!self) | ||||
|     return -1; | ||||
|  | ||||
|   priv = self->priv; | ||||
|  | ||||
|   if (!priv->window || meta_window_is_on_all_workspaces (priv->window)) | ||||
|     return -1; | ||||
|  | ||||
|   workspace = meta_window_get_workspace (priv->window); | ||||
|  | ||||
|   if (!workspace) | ||||
|     return -1; | ||||
|  | ||||
|   return meta_workspace_index (workspace); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_window_actor_showing_on_its_workspace (MetaWindowActor *self) | ||||
| { | ||||
|   if (!self) | ||||
|     return FALSE; | ||||
|  | ||||
|   /* If override redirect: */ | ||||
|   if (!self->priv->window) | ||||
|     return TRUE; | ||||
|  | ||||
|   return meta_window_showing_on_its_workspace (self->priv->window); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_window_actor_freeze (MetaWindowActor *self) | ||||
| { | ||||
| @@ -1362,7 +1245,7 @@ meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state) | ||||
|   MetaDisplay *display = meta_window_get_display (metaWindow); | ||||
|  | ||||
|   Display *xdisplay = meta_display_get_xdisplay (display); | ||||
|   Window  xwin = meta_window_actor_get_x_window (self); | ||||
|   Window  xwin = meta_window_get_toplevel_xwindow (metaWindow); | ||||
|  | ||||
|   if (state) | ||||
|     { | ||||
| @@ -1385,7 +1268,6 @@ void | ||||
| meta_window_actor_destroy (MetaWindowActor *self) | ||||
| { | ||||
|   MetaWindow	      *window; | ||||
|   MetaCompScreen      *info; | ||||
|   MetaWindowActorPrivate *priv; | ||||
|   MetaWindowType window_type; | ||||
|  | ||||
| @@ -1393,14 +1275,6 @@ meta_window_actor_destroy (MetaWindowActor *self) | ||||
|  | ||||
|   window = priv->window; | ||||
|   window_type = meta_window_get_window_type (window); | ||||
|   meta_window_set_compositor_private (window, NULL); | ||||
|  | ||||
|   /* | ||||
|    * We remove the window from internal lookup hashes and thus any other | ||||
|    * unmap events etc fail | ||||
|    */ | ||||
|   info = meta_screen_get_compositor_data (priv->screen); | ||||
|   info->windows = g_list_remove (info->windows, (gconstpointer) self); | ||||
|  | ||||
|   if (window_type == META_WINDOW_DROPDOWN_MENU || | ||||
|       window_type == META_WINDOW_POPUP_MENU || | ||||
| @@ -1463,8 +1337,6 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self, | ||||
|                               window_rect.x, window_rect.y); | ||||
|   clutter_actor_set_size (CLUTTER_ACTOR (self), | ||||
|                           window_rect.width, window_rect.height); | ||||
|  | ||||
|   g_signal_emit (self, signals[POSITION_CHANGED], 0); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -1612,68 +1484,9 @@ meta_window_actor_unmaximize (MetaWindowActor   *self, | ||||
| MetaWindowActor * | ||||
| meta_window_actor_new (MetaWindow *window) | ||||
| { | ||||
|   MetaScreen	 	 *screen = meta_window_get_screen (window); | ||||
|   MetaCompScreen         *info = meta_screen_get_compositor_data (screen); | ||||
|   MetaWindowActor        *self; | ||||
|   MetaWindowActorPrivate *priv; | ||||
|   MetaFrame		 *frame; | ||||
|   Window		  top_window; | ||||
|   ClutterActor           *window_group; | ||||
|  | ||||
|   frame = meta_window_get_frame (window); | ||||
|   if (frame) | ||||
|     top_window = meta_frame_get_xwindow (frame); | ||||
|   else | ||||
|     top_window = meta_window_get_xwindow (window); | ||||
|  | ||||
|   meta_verbose ("add window: Meta %p, xwin 0x%x\n", window, (guint)top_window); | ||||
|  | ||||
|   self = g_object_new (META_TYPE_WINDOW_ACTOR, | ||||
|                        "meta-window",         window, | ||||
|                        "x-window",            top_window, | ||||
|                        "meta-screen",         screen, | ||||
|   return g_object_new (META_TYPE_WINDOW_ACTOR, | ||||
|                        "meta-window", window, | ||||
|                        NULL); | ||||
|  | ||||
|   priv = self->priv; | ||||
|  | ||||
|   priv->last_width = -1; | ||||
|   priv->last_height = -1; | ||||
|  | ||||
|   priv->mapped = meta_window_toplevel_is_mapped (priv->window); | ||||
|   if (priv->mapped) | ||||
|     meta_window_actor_queue_create_pixmap (self); | ||||
|  | ||||
|   meta_window_actor_set_updates_frozen (self, | ||||
|                                         meta_window_updates_are_frozen (priv->window)); | ||||
|  | ||||
|   /* If a window doesn't start off with updates frozen, we should | ||||
|    * we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn. | ||||
|    */ | ||||
|   if (priv->window->extended_sync_request_counter && !priv->updates_frozen) | ||||
|     meta_window_actor_queue_frame_drawn (self, FALSE); | ||||
|  | ||||
|   meta_window_actor_sync_actor_geometry (self, priv->window->placed); | ||||
|  | ||||
|   /* Hang our compositor window state off the MetaWindow for fast retrieval */ | ||||
|   meta_window_set_compositor_private (window, G_OBJECT (self)); | ||||
|  | ||||
|   if (window->layer == META_LAYER_OVERRIDE_REDIRECT) | ||||
|     window_group = info->top_window_group; | ||||
|   else | ||||
|     window_group = info->window_group; | ||||
|  | ||||
|   clutter_actor_add_child (window_group, CLUTTER_ACTOR (self)); | ||||
|  | ||||
|   clutter_actor_hide (CLUTTER_ACTOR (self)); | ||||
|  | ||||
|   clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); | ||||
|  | ||||
|   /* Initial position in the stack is arbitrary; stacking will be synced | ||||
|    * before we first paint. | ||||
|    */ | ||||
|   info->windows = g_list_append (info->windows, self); | ||||
|  | ||||
|   return self; | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -1714,7 +1527,7 @@ meta_window_actor_unmapped (MetaWindowActor *self) | ||||
|  * Return value: (transfer none): the area obscured by the window, | ||||
|  *  %NULL is the same as an empty region. | ||||
|  */ | ||||
| cairo_region_t * | ||||
| static cairo_region_t * | ||||
| meta_window_actor_get_obscured_region (MetaWindowActor *self) | ||||
| { | ||||
|   MetaWindowActorPrivate *priv = self->priv; | ||||
| @@ -1803,7 +1616,7 @@ meta_window_actor_set_unobscured_region (MetaWindowActor *self, | ||||
|  * not drawn in this frame. | ||||
|  * This will be set before painting then unset afterwards. | ||||
|  */ | ||||
| void | ||||
| static void | ||||
| meta_window_actor_set_clip_region (MetaWindowActor *self, | ||||
|                                    cairo_region_t  *clip_region) | ||||
| { | ||||
| @@ -1825,7 +1638,7 @@ meta_window_actor_set_clip_region (MetaWindowActor *self, | ||||
|  * shadow hid by the window itself. This will be set before painting | ||||
|  * then unset afterwards. | ||||
|  */ | ||||
| void | ||||
| static void | ||||
| meta_window_actor_set_clip_region_beneath (MetaWindowActor *self, | ||||
|                                            cairo_region_t  *beneath_region) | ||||
| { | ||||
| @@ -1845,16 +1658,38 @@ meta_window_actor_set_clip_region_beneath (MetaWindowActor *self, | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_window_actor_reset_clip_regions: | ||||
|  * @self: a #MetaWindowActor | ||||
|  * | ||||
|  * Unsets the regions set by meta_window_actor_set_clip_region() and | ||||
|  * meta_window_actor_set_clip_region_beneath() | ||||
|  */ | ||||
| void | ||||
| meta_window_actor_reset_clip_regions (MetaWindowActor *self) | ||||
| static void | ||||
| meta_window_actor_cull_out (MetaCullable   *cullable, | ||||
|                             cairo_region_t *unobscured_region, | ||||
|                             cairo_region_t *clip_region) | ||||
| { | ||||
|   MetaWindowActor *self = META_WINDOW_ACTOR (cullable); | ||||
|   MetaCompScreen *info = meta_screen_get_compositor_data (self->priv->screen); | ||||
|  | ||||
|   /* Don't do any culling for the unredirected window */ | ||||
|   if (self == info->unredirected_window) | ||||
|     return; | ||||
|  | ||||
|   meta_window_actor_set_unobscured_region (self, unobscured_region); | ||||
|   meta_window_actor_set_clip_region (self, clip_region); | ||||
|  | ||||
|   if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self)) == 0xff) | ||||
|     { | ||||
|       cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (self); | ||||
|       if (obscured_region) | ||||
|         { | ||||
|           cairo_region_subtract (unobscured_region, obscured_region); | ||||
|           cairo_region_subtract (clip_region, obscured_region); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   meta_window_actor_set_clip_region_beneath (self, clip_region); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_window_actor_reset_culling (MetaCullable *cullable) | ||||
| { | ||||
|   MetaWindowActor *self = META_WINDOW_ACTOR (cullable); | ||||
|   MetaWindowActorPrivate *priv = self->priv; | ||||
|  | ||||
|   meta_shaped_texture_set_clip_region (META_SHAPED_TEXTURE (priv->actor), | ||||
| @@ -1862,6 +1697,13 @@ meta_window_actor_reset_clip_regions (MetaWindowActor *self) | ||||
|   g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); | ||||
| } | ||||
|  | ||||
| static void | ||||
| cullable_iface_init (MetaCullableInterface *iface) | ||||
| { | ||||
|   iface->cull_out = meta_window_actor_cull_out; | ||||
|   iface->reset_culling = meta_window_actor_reset_culling; | ||||
| } | ||||
|  | ||||
| static void | ||||
| check_needs_pixmap (MetaWindowActor *self) | ||||
| { | ||||
| @@ -1870,8 +1712,8 @@ check_needs_pixmap (MetaWindowActor *self) | ||||
|   MetaDisplay         *display  = meta_screen_get_display (screen); | ||||
|   Display             *xdisplay = meta_display_get_xdisplay (display); | ||||
|   MetaCompScreen      *info     = meta_screen_get_compositor_data (screen); | ||||
|   Window               xwindow  = meta_window_get_toplevel_xwindow (priv->window); | ||||
|   MetaCompositor      *compositor; | ||||
|   Window               xwindow  = priv->xwindow; | ||||
|  | ||||
|   if (!priv->needs_pixmap) | ||||
|     return; | ||||
| @@ -1935,17 +1777,6 @@ check_needs_pixmap (MetaWindowActor *self) | ||||
|        */ | ||||
|       if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture)))) | ||||
|         g_warning ("NOTE: Not using GLX TFP!\n"); | ||||
|  | ||||
|       /* ::size-changed is supposed to refer to meta_window_get_outer_rect(). | ||||
|        * Emitting it here works pretty much OK because a new value of the | ||||
|        * *input* rect (which is the outer rect with the addition of invisible | ||||
|        * borders) forces a new pixmap and we get here. In the rare case where | ||||
|        * a change to the window size was exactly balanced by a change to the | ||||
|        * invisible borders, we would miss emitting the signal. We would also | ||||
|        * emit spurious signals when we get a new pixmap without a new size, | ||||
|        * but that should be mostly harmless. | ||||
|        */ | ||||
|       g_signal_emit (self, signals[SIZE_CHANGED], 0); | ||||
|     } | ||||
|  | ||||
|   priv->needs_pixmap = FALSE; | ||||
| @@ -2032,7 +1863,7 @@ meta_window_actor_process_damage (MetaWindowActor    *self, | ||||
|   if (meta_window_is_fullscreen (priv->window) && g_list_last (info->windows)->data == self && !priv->unredirected) | ||||
|     { | ||||
|       MetaRectangle window_rect; | ||||
|       meta_window_get_outer_rect (priv->window, &window_rect); | ||||
|       meta_window_get_frame_rect (priv->window, &window_rect); | ||||
|  | ||||
|       if (window_rect.x == event->area.x && | ||||
|           window_rect.y == event->area.y && | ||||
| @@ -2256,9 +2087,46 @@ meta_window_actor_update_shape_region (MetaWindowActor       *self, | ||||
|   priv->shape_region = region; | ||||
|  | ||||
|   g_clear_pointer (&priv->shadow_shape, meta_window_shape_unref); | ||||
|  | ||||
|   meta_window_actor_invalidate_shadow (self); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_window_actor_update_input_region (MetaWindowActor       *self, | ||||
|                                        cairo_rectangle_int_t *client_area) | ||||
| { | ||||
|   MetaWindowActorPrivate *priv = self->priv; | ||||
|   MetaShapedTexture *stex = META_SHAPED_TEXTURE (priv->actor); | ||||
|   cairo_region_t *region = NULL; | ||||
|  | ||||
|   if (priv->window->frame != NULL && priv->window->input_region != NULL) | ||||
|     { | ||||
|       region = meta_frame_get_frame_bounds (priv->window->frame); | ||||
|  | ||||
|       cairo_region_subtract_rectangle (region, client_area); | ||||
|  | ||||
|       /* input_region is in client window coordinates, so translate the | ||||
|        * input region into that coordinate system and back */ | ||||
|       cairo_region_translate (region, -client_area->x, -client_area->y); | ||||
|       cairo_region_union (region, priv->window->input_region); | ||||
|       cairo_region_translate (region, client_area->x, client_area->y); | ||||
|     } | ||||
|   else if (priv->window->input_region != NULL) | ||||
|     { | ||||
|       region = cairo_region_reference (priv->window->input_region); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* If we don't have a shape on the server, that means that | ||||
|        * we have an implicit shape of one rectangle covering the | ||||
|        * entire window. */ | ||||
|       region = cairo_region_create_rectangle (client_area); | ||||
|     } | ||||
|  | ||||
|   meta_shaped_texture_set_input_shape_region (stex, region); | ||||
|   cairo_region_destroy (region); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_window_actor_update_opaque_region (MetaWindowActor *self) | ||||
| { | ||||
| @@ -2319,10 +2187,10 @@ check_needs_reshape (MetaWindowActor *self) | ||||
|     client_area.height = priv->window->rect.height; | ||||
|  | ||||
|   meta_window_actor_update_shape_region (self, &client_area); | ||||
|   meta_window_actor_update_input_region (self, &client_area); | ||||
|   meta_window_actor_update_opaque_region (self); | ||||
|  | ||||
|   priv->needs_reshape = FALSE; | ||||
|   meta_window_actor_invalidate_shadow (self); | ||||
| } | ||||
|  | ||||
| void | ||||
|   | ||||
| @@ -11,8 +11,8 @@ | ||||
| #include "compositor-private.h" | ||||
| #include "meta-window-actor-private.h" | ||||
| #include "meta-window-group.h" | ||||
| #include "meta-background-actor-private.h" | ||||
| #include "meta-background-group-private.h" | ||||
| #include "window-private.h" | ||||
| #include "meta-cullable.h" | ||||
|  | ||||
| struct _MetaWindowGroupClass | ||||
| { | ||||
| @@ -26,7 +26,10 @@ struct _MetaWindowGroup | ||||
|   MetaScreen *screen; | ||||
| }; | ||||
|  | ||||
| G_DEFINE_TYPE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR); | ||||
| static void cullable_iface_init (MetaCullableInterface *iface); | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_CODE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR, | ||||
|                          G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); | ||||
|  | ||||
| /* Help macros to scale from OpenGL <-1,1> coordinates system to | ||||
|  * window coordinates ranging [0,window-size]. Borrowed from clutter-utils.c | ||||
| @@ -86,6 +89,27 @@ painting_untransformed (MetaWindowGroup *window_group, | ||||
|   return meta_actor_vertices_are_untransformed (vertices, width, height, x_origin, y_origin); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_window_group_cull_out (MetaCullable   *cullable, | ||||
|                             cairo_region_t *unobscured_region, | ||||
|                             cairo_region_t *clip_region) | ||||
| { | ||||
|   meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_window_group_reset_culling (MetaCullable *cullable) | ||||
| { | ||||
|   meta_cullable_reset_culling_children (cullable); | ||||
| } | ||||
|  | ||||
| static void | ||||
| cullable_iface_init (MetaCullableInterface *iface) | ||||
| { | ||||
|   iface->cull_out = meta_window_group_cull_out; | ||||
|   iface->reset_culling = meta_window_group_reset_culling; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_window_group_paint (ClutterActor *actor) | ||||
| { | ||||
| @@ -94,13 +118,13 @@ meta_window_group_paint (ClutterActor *actor) | ||||
|   ClutterActorIter iter; | ||||
|   ClutterActor *child; | ||||
|   cairo_rectangle_int_t visible_rect, clip_rect; | ||||
|   int paint_x_offset, paint_y_offset; | ||||
|   int paint_x_origin, paint_y_origin; | ||||
|   int actor_x_origin, actor_y_origin; | ||||
|   int paint_x_offset, paint_y_offset; | ||||
|  | ||||
|   MetaWindowGroup *window_group = META_WINDOW_GROUP (actor); | ||||
|   MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen); | ||||
|   ClutterActor *stage = clutter_actor_get_stage (actor); | ||||
|   MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen); | ||||
|  | ||||
|   /* Start off by treating all windows as completely unobscured, so damage anywhere | ||||
|    * in a window queues redraws, but confine it more below. */ | ||||
| @@ -134,9 +158,6 @@ meta_window_group_paint (ClutterActor *actor) | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   paint_x_offset = paint_x_origin - actor_x_origin; | ||||
|   paint_y_offset = paint_y_origin - actor_y_origin; | ||||
|  | ||||
|   visible_rect.x = visible_rect.y = 0; | ||||
|   visible_rect.width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); | ||||
|   visible_rect.height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); | ||||
| @@ -154,134 +175,54 @@ meta_window_group_paint (ClutterActor *actor) | ||||
|  | ||||
|   clip_region = cairo_region_create_rectangle (&clip_rect); | ||||
|  | ||||
|   paint_x_offset = paint_x_origin - actor_x_origin; | ||||
|   paint_y_offset = paint_y_origin - actor_y_origin; | ||||
|   cairo_region_translate (clip_region, -paint_x_offset, -paint_y_offset); | ||||
|  | ||||
|   if (info->unredirected_window != NULL) | ||||
|     { | ||||
|       cairo_rectangle_int_t unredirected_rect; | ||||
|       MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window); | ||||
|  | ||||
|       meta_window_get_outer_rect (window, (MetaRectangle *)&unredirected_rect); | ||||
|       meta_window_get_frame_rect (window, (MetaRectangle *)&unredirected_rect); | ||||
|       cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect); | ||||
|       cairo_region_subtract_rectangle (clip_region, &unredirected_rect); | ||||
|     } | ||||
|  | ||||
|   /* We walk the list from top to bottom (opposite of painting order), | ||||
|    * and subtract the opaque area of each window out of the visible | ||||
|    * region that we pass to the windows below. | ||||
|    */ | ||||
|   clutter_actor_iter_init (&iter, actor); | ||||
|   while (clutter_actor_iter_prev (&iter, &child)) | ||||
|     { | ||||
|       if (!CLUTTER_ACTOR_IS_VISIBLE (child)) | ||||
|         continue; | ||||
|  | ||||
|       if (info->unredirected_window != NULL && | ||||
|           child == CLUTTER_ACTOR (info->unredirected_window)) | ||||
|         continue; | ||||
|  | ||||
|       /* If an actor has effects applied, then that can change the area | ||||
|        * it paints and the opacity, so we no longer can figure out what | ||||
|        * portion of the actor is obscured and what portion of the screen | ||||
|        * it obscures, so we skip the actor. | ||||
|        * | ||||
|        * This has a secondary beneficial effect: if a ClutterOffscreenEffect | ||||
|        * is applied to an actor, then our clipped redraws interfere with the | ||||
|        * caching of the FBO - even if we only need to draw a small portion | ||||
|        * of the window right now, ClutterOffscreenEffect may use other portions | ||||
|        * of the FBO later. So, skipping actors with effects applied also | ||||
|        * prevents these bugs. | ||||
|        * | ||||
|        * Theoretically, we should check clutter_actor_get_offscreen_redirect() | ||||
|        * as well for the same reason, but omitted for simplicity in the | ||||
|        * hopes that no-one will do that. | ||||
|        */ | ||||
|       if (clutter_actor_has_effects (child)) | ||||
|         continue; | ||||
|  | ||||
|       if (META_IS_WINDOW_ACTOR (child)) | ||||
|         { | ||||
|           MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); | ||||
|           int x, y; | ||||
|  | ||||
|           if (!meta_actor_is_untransformed (CLUTTER_ACTOR (window_actor), &x, &y)) | ||||
|             continue; | ||||
|  | ||||
|           x += paint_x_offset; | ||||
|           y += paint_y_offset; | ||||
|  | ||||
|  | ||||
|           /* Temporarily move to the coordinate system of the actor */ | ||||
|           cairo_region_translate (unobscured_region, - x, - y); | ||||
|           cairo_region_translate (clip_region, - x, - y); | ||||
|  | ||||
|           meta_window_actor_set_unobscured_region (window_actor, unobscured_region); | ||||
|           meta_window_actor_set_clip_region (window_actor, clip_region); | ||||
|  | ||||
|           if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff) | ||||
|             { | ||||
|               cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (window_actor); | ||||
|               if (obscured_region) | ||||
|                 { | ||||
|                   cairo_region_subtract (unobscured_region, obscured_region); | ||||
|                   cairo_region_subtract (clip_region, obscured_region); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|           meta_window_actor_set_clip_region_beneath (window_actor, clip_region); | ||||
|  | ||||
|           cairo_region_translate (unobscured_region, x, y); | ||||
|           cairo_region_translate (clip_region, x, y); | ||||
|         } | ||||
|       else if (META_IS_BACKGROUND_ACTOR (child) || | ||||
|                META_IS_BACKGROUND_GROUP (child)) | ||||
|         { | ||||
|           int x, y; | ||||
|  | ||||
|           if (!meta_actor_is_untransformed (child, &x, &y)) | ||||
|             continue; | ||||
|  | ||||
|           x += paint_x_offset; | ||||
|           y += paint_y_offset; | ||||
|  | ||||
|           cairo_region_translate (clip_region, - x, - y); | ||||
|  | ||||
|           if (META_IS_BACKGROUND_GROUP (child)) | ||||
|             meta_background_group_set_clip_region (META_BACKGROUND_GROUP (child), clip_region); | ||||
|           else | ||||
|             meta_background_actor_set_clip_region (META_BACKGROUND_ACTOR (child), clip_region); | ||||
|  | ||||
|           cairo_region_translate (clip_region, x, y); | ||||
|         } | ||||
|     } | ||||
|   meta_cullable_cull_out (META_CULLABLE (window_group), unobscured_region, clip_region); | ||||
|  | ||||
|   cairo_region_destroy (unobscured_region); | ||||
|   cairo_region_destroy (clip_region); | ||||
|  | ||||
|   CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor); | ||||
|  | ||||
|   /* Now that we are done painting, unset the visible regions (they will | ||||
|    * mess up painting clones of our actors) | ||||
|    */ | ||||
|   clutter_actor_iter_init (&iter, actor); | ||||
|   while (clutter_actor_iter_next (&iter, &child)) | ||||
|     { | ||||
|       if (META_IS_WINDOW_ACTOR (child)) | ||||
|         { | ||||
|           MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); | ||||
|           meta_window_actor_reset_clip_regions (window_actor); | ||||
|         } | ||||
|       else if (META_IS_BACKGROUND_ACTOR (child)) | ||||
|         { | ||||
|           MetaBackgroundActor *background_actor = META_BACKGROUND_ACTOR (child); | ||||
|           meta_background_actor_set_clip_region (background_actor, NULL); | ||||
|         } | ||||
|     } | ||||
|   meta_cullable_reset_culling (META_CULLABLE (window_group)); | ||||
| } | ||||
|  | ||||
| /* Adapted from clutter_actor_update_default_paint_volume() */ | ||||
| static gboolean | ||||
| meta_window_group_get_paint_volume (ClutterActor       *actor, | ||||
| meta_window_group_get_paint_volume (ClutterActor       *self, | ||||
|                                     ClutterPaintVolume *volume) | ||||
| { | ||||
|   return clutter_paint_volume_set_from_allocation (volume, actor); | ||||
|   ClutterActorIter iter; | ||||
|   ClutterActor *child; | ||||
|  | ||||
|   clutter_actor_iter_init (&iter, self); | ||||
|   while (clutter_actor_iter_next (&iter, &child)) | ||||
|     { | ||||
|       const ClutterPaintVolume *child_volume; | ||||
|  | ||||
|       if (!CLUTTER_ACTOR_IS_MAPPED (child)) | ||||
|         continue; | ||||
|  | ||||
|       child_volume = clutter_actor_get_transformed_paint_volume (child, self); | ||||
|       if (child_volume == NULL) | ||||
|         return FALSE; | ||||
|  | ||||
|       clutter_paint_volume_union (volume, child_volume); | ||||
|     } | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
|   | ||||
| @@ -11,29 +11,9 @@ | ||||
|  * MetaWindowGroup: | ||||
|  * | ||||
|  * This class is a subclass of ClutterActor with special handling for | ||||
|  * MetaWindowActor/MetaBackgroundActor/MetaBackgroundGroup when painting | ||||
|  * children. | ||||
|  * | ||||
|  * When we are painting a stack of 5-10 maximized windows, the | ||||
|  * standard bottom-to-top method of drawing every actor results in a | ||||
|  * tremendous amount of overdraw and can easily max out the available | ||||
|  * memory bandwidth on a low-end graphics chipset. It's even worse if | ||||
|  * window textures are being accessed over the AGP bus. | ||||
|  * | ||||
|  * The basic technique applied here is to do a pre-pass before painting | ||||
|  * where we walk window from top to bottom and compute the visible area | ||||
|  * at each step by subtracting out the windows above it. The visible | ||||
|  * area is passed to MetaWindowActor which uses it to clip the portion of | ||||
|  * the window which drawn and avoid redrawing the shadow if it is completely | ||||
|  * obscured. | ||||
|  * | ||||
|  * A caveat is that this is ineffective if applications are using ARGB | ||||
|  * visuals, since we have no way of knowing whether a window obscures | ||||
|  * the windows behind it or not. Alternate approaches using the depth | ||||
|  * or stencil buffer rather than client side regions might be able to | ||||
|  * handle alpha windows, but the combination of glAlphaFunc and stenciling | ||||
|  * tends not to be efficient except on newer cards. (And on newer cards | ||||
|  * we have lots of memory and bandwidth.) | ||||
|  * #MetaCullable when painting children. It uses code similar to | ||||
|  * meta_cullable_cull_out_children(), but also has additional special | ||||
|  * cases for the undirected window, and similar. | ||||
|  */ | ||||
|  | ||||
| #define META_TYPE_WINDOW_GROUP            (meta_window_group_get_type ()) | ||||
|   | ||||
| @@ -412,7 +412,7 @@ switch_workspace (MetaPlugin *plugin, | ||||
|       ClutterActor    *actor	    = CLUTTER_ACTOR (window_actor); | ||||
|       gint             win_workspace; | ||||
|  | ||||
|       win_workspace = meta_window_actor_get_workspace (window_actor); | ||||
|       win_workspace = meta_window_get_workspace (meta_window_actor_get_meta_window (window_actor)); | ||||
|  | ||||
|       if (win_workspace == to || win_workspace == from) | ||||
|         { | ||||
|   | ||||
| @@ -118,8 +118,6 @@ typedef struct | ||||
| { | ||||
|   MetaRectangle        orig; | ||||
|   MetaRectangle        current; | ||||
|   MetaFrameBorders    *borders; | ||||
|   gboolean             must_free_borders; | ||||
|   ActionType           action_type; | ||||
|   gboolean             is_user_action; | ||||
|  | ||||
| @@ -195,7 +193,6 @@ static gboolean constrain_partially_onscreen (MetaWindow         *window, | ||||
|  | ||||
| static void setup_constraint_info        (ConstraintInfo      *info, | ||||
|                                           MetaWindow          *window, | ||||
|                                           MetaFrameBorders    *orig_borders, | ||||
|                                           MetaMoveResizeFlags  flags, | ||||
|                                           int                  resize_gravity, | ||||
|                                           const MetaRectangle *orig, | ||||
| @@ -204,13 +201,12 @@ static void place_window_if_needed       (MetaWindow     *window, | ||||
|                                           ConstraintInfo *info); | ||||
| static void update_onscreen_requirements (MetaWindow     *window, | ||||
|                                           ConstraintInfo *info); | ||||
| static void extend_by_frame              (MetaRectangle           *rect, | ||||
|                                           const MetaFrameBorders  *borders); | ||||
| static void unextend_by_frame            (MetaRectangle           *rect, | ||||
|                                           const MetaFrameBorders  *borders); | ||||
| static inline void get_size_limits       (const MetaWindow        *window, | ||||
|                                           const MetaFrameBorders  *borders, | ||||
|                                           gboolean include_frame, | ||||
| static void extend_by_frame              (MetaWindow     *window, | ||||
|                                           MetaRectangle  *rect); | ||||
| static void unextend_by_frame            (MetaWindow     *window, | ||||
|                                           MetaRectangle  *rect); | ||||
| static inline void get_size_limits       (MetaWindow    *window, | ||||
|                                           gboolean       include_frame, | ||||
|                                           MetaRectangle *min_size, | ||||
|                                           MetaRectangle *max_size); | ||||
|  | ||||
| @@ -280,7 +276,6 @@ do_all_constraints (MetaWindow         *window, | ||||
|  | ||||
| void | ||||
| meta_window_constrain (MetaWindow          *window, | ||||
|                        MetaFrameBorders    *orig_borders, | ||||
|                        MetaMoveResizeFlags  flags, | ||||
|                        int                  resize_gravity, | ||||
|                        const MetaRectangle *orig, | ||||
| @@ -303,7 +298,6 @@ meta_window_constrain (MetaWindow          *window, | ||||
|  | ||||
|   setup_constraint_info (&info, | ||||
|                          window,  | ||||
|                          orig_borders, | ||||
|                          flags, | ||||
|                          resize_gravity, | ||||
|                          orig, | ||||
| @@ -333,19 +327,11 @@ meta_window_constrain (MetaWindow          *window, | ||||
|    * if this was a user move or user move-and-resize operation. | ||||
|    */ | ||||
|   update_onscreen_requirements (window, &info); | ||||
|  | ||||
|   /* Ew, what an ugly way to do things.  Destructors (in a real OOP language, | ||||
|    * not gobject-style--gobject would be more pain than it's worth) or | ||||
|    * smart pointers would be so much nicer here.  *shrug* | ||||
|    */ | ||||
|   if (info.must_free_borders) | ||||
|     g_free (info.borders); | ||||
| } | ||||
|  | ||||
| static void | ||||
| setup_constraint_info (ConstraintInfo      *info, | ||||
|                        MetaWindow          *window, | ||||
|                        MetaFrameBorders    *orig_borders, | ||||
|                        MetaMoveResizeFlags  flags, | ||||
|                        int                  resize_gravity, | ||||
|                        const MetaRectangle *orig, | ||||
| @@ -357,18 +343,6 @@ setup_constraint_info (ConstraintInfo      *info, | ||||
|   info->orig    = *orig; | ||||
|   info->current = *new; | ||||
|  | ||||
|   /* Create a fake frame geometry if none really exists */ | ||||
|   if (orig_borders && !window->fullscreen) | ||||
|     { | ||||
|       info->borders = orig_borders; | ||||
|       info->must_free_borders = FALSE; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       info->borders = g_new0 (MetaFrameBorders, 1); | ||||
|       info->must_free_borders = TRUE; | ||||
|     } | ||||
|  | ||||
|   if (flags & META_IS_MOVE_ACTION && flags & META_IS_RESIZE_ACTION) | ||||
|     info->action_type = ACTION_MOVE_AND_RESIZE; | ||||
|   else if (flags & META_IS_RESIZE_ACTION) | ||||
| @@ -519,11 +493,12 @@ place_window_if_needed(MetaWindow     *window, | ||||
|       !window->minimized && | ||||
|       !window->fullscreen) | ||||
|     { | ||||
|       MetaRectangle placed_rect = info->orig; | ||||
|       MetaRectangle placed_rect; | ||||
|       MetaWorkspace *cur_workspace; | ||||
|       const MetaMonitorInfo *monitor_info; | ||||
|  | ||||
|       meta_window_place (window, info->borders, info->orig.x, info->orig.y, | ||||
|       meta_window_get_frame_rect (window, &placed_rect); | ||||
|       meta_window_place (window, info->orig.x, info->orig.y, | ||||
|                          &placed_rect.x, &placed_rect.y); | ||||
|       did_placement = TRUE; | ||||
|  | ||||
| @@ -541,6 +516,7 @@ place_window_if_needed(MetaWindow     *window, | ||||
|         meta_workspace_get_onmonitor_region (cur_workspace,  | ||||
|                                              monitor_info->number); | ||||
|  | ||||
|       meta_window_frame_rect_to_client_rect (window, &placed_rect, &placed_rect); | ||||
|  | ||||
|       info->current.x = placed_rect.x; | ||||
|       info->current.y = placed_rect.y; | ||||
| @@ -586,10 +562,6 @@ place_window_if_needed(MetaWindow     *window, | ||||
|                 (window->maximize_vertically_after_placement ? | ||||
|                  META_MAXIMIZE_VERTICAL : 0), &info->current); | ||||
|  | ||||
|           /* maximization may have changed frame geometry */ | ||||
|           if (!window->fullscreen) | ||||
|             meta_frame_calc_borders (window->frame, info->borders); | ||||
|  | ||||
|           if (window->fullscreen_after_placement) | ||||
|             { | ||||
|               window->saved_rect = info->current; | ||||
| @@ -649,7 +621,7 @@ update_onscreen_requirements (MetaWindow     *window, | ||||
|   /* The require onscreen/on-single-monitor and titlebar_visible | ||||
|    * stuff is relative to the outer window, not the inner | ||||
|    */ | ||||
|   extend_by_frame (&info->current, info->borders); | ||||
|   extend_by_frame (window, &info->current); | ||||
|  | ||||
|   /* Update whether we want future constraint runs to require the | ||||
|    * window to be on fully onscreen. | ||||
| @@ -682,10 +654,13 @@ update_onscreen_requirements (MetaWindow     *window, | ||||
|    */ | ||||
|   if (window->frame && window->decorated) | ||||
|     { | ||||
|       MetaFrameBorders borders; | ||||
|       MetaRectangle titlebar_rect; | ||||
|  | ||||
|       meta_frame_calc_borders (window->frame, &borders); | ||||
|  | ||||
|       titlebar_rect = info->current; | ||||
|       titlebar_rect.height = info->borders->visible.top; | ||||
|       titlebar_rect.height = borders.visible.top; | ||||
|       old = window->require_titlebar_visible; | ||||
|       window->require_titlebar_visible = | ||||
|         meta_rectangle_overlaps_with_region (info->usable_screen_region, | ||||
| @@ -698,39 +673,33 @@ update_onscreen_requirements (MetaWindow     *window, | ||||
|     } | ||||
|  | ||||
|   /* Don't forget to restore the position of the window */ | ||||
|   unextend_by_frame (&info->current, info->borders); | ||||
|   unextend_by_frame (window, &info->current); | ||||
| } | ||||
|  | ||||
| static void | ||||
| extend_by_frame (MetaRectangle           *rect, | ||||
|                  const MetaFrameBorders *borders) | ||||
| extend_by_frame (MetaWindow    *window, | ||||
|                  MetaRectangle *rect) | ||||
| { | ||||
|   rect->x -= borders->visible.left; | ||||
|   rect->y -= borders->visible.top; | ||||
|   rect->width  += borders->visible.left + borders->visible.right; | ||||
|   rect->height += borders->visible.top + borders->visible.bottom; | ||||
|   meta_window_client_rect_to_frame_rect (window, rect, rect); | ||||
| } | ||||
|  | ||||
| static void | ||||
| unextend_by_frame (MetaRectangle           *rect, | ||||
|                    const MetaFrameBorders *borders) | ||||
| unextend_by_frame (MetaWindow    *window, | ||||
|                    MetaRectangle *rect) | ||||
| { | ||||
|   rect->x += borders->visible.left; | ||||
|   rect->y += borders->visible.top; | ||||
|   rect->width  -= borders->visible.left + borders->visible.right; | ||||
|   rect->height -= borders->visible.top + borders->visible.bottom; | ||||
|   meta_window_frame_rect_to_client_rect (window, rect, rect); | ||||
| } | ||||
|  | ||||
| static inline void | ||||
| get_size_limits (const MetaWindow        *window, | ||||
|                  const MetaFrameBorders *borders, | ||||
|                  gboolean                 include_frame, | ||||
| get_size_limits (MetaWindow    *window, | ||||
|                  gboolean       include_frame, | ||||
|                  MetaRectangle *min_size, | ||||
|                  MetaRectangle *max_size) | ||||
| { | ||||
|   /* We pack the results into MetaRectangle structs just for convienience; we | ||||
|    * don't actually use the position of those rects. | ||||
|    */ | ||||
|   min_size->x = min_size->y = max_size->x = max_size->y = 0; | ||||
|   min_size->width  = window->size_hints.min_width; | ||||
|   min_size->height = window->size_hints.min_height; | ||||
|   max_size->width  = window->size_hints.max_width; | ||||
| @@ -738,22 +707,8 @@ get_size_limits (const MetaWindow        *window, | ||||
|  | ||||
|   if (include_frame) | ||||
|     { | ||||
|       int fw = borders->visible.left + borders->visible.right; | ||||
|       int fh = borders->visible.top + borders->visible.bottom; | ||||
|  | ||||
|       min_size->width  += fw; | ||||
|       min_size->height += fh; | ||||
|       /* Do check to avoid overflow (e.g. max_size->width & max_size->height | ||||
|        * may be set to G_MAXINT by meta_set_normal_hints()). | ||||
|        */ | ||||
|       if (max_size->width < (G_MAXINT - fw)) | ||||
|         max_size->width += fw; | ||||
|       else | ||||
|         max_size->width = G_MAXINT; | ||||
|       if (max_size->height < (G_MAXINT - fh)) | ||||
|         max_size->height += fh; | ||||
|       else | ||||
|         max_size->height = G_MAXINT; | ||||
|       meta_window_client_rect_to_frame_rect (window, min_size, min_size); | ||||
|       meta_window_client_rect_to_frame_rect (window, max_size, max_size); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -765,18 +720,28 @@ constrain_modal_dialog (MetaWindow         *window, | ||||
| { | ||||
|   int x, y; | ||||
|   MetaWindow *parent = meta_window_get_transient_for (window); | ||||
|   MetaRectangle child_rect, parent_rect; | ||||
|   gboolean constraint_already_satisfied; | ||||
|  | ||||
|   if (!meta_window_is_attached_dialog (window)) | ||||
|     return TRUE; | ||||
|  | ||||
|   x = parent->rect.x + (parent->rect.width / 2  - info->current.width / 2); | ||||
|   y = parent->rect.y + (parent->rect.height / 2 - info->current.height / 2); | ||||
|   if (parent->frame) | ||||
|     { | ||||
|       x += parent->frame->rect.x; | ||||
|       y += parent->frame->rect.y; | ||||
|     } | ||||
|   /* We want to center the dialog on the parent, including the decorations | ||||
|      for both of them. info->current is in client X window coordinates, so we need | ||||
|      to convert them to frame coordinates, apply the centering and then | ||||
|      convert back to client. | ||||
|   */ | ||||
|  | ||||
|   child_rect = info->current; | ||||
|   extend_by_frame (window, &child_rect); | ||||
|  | ||||
|   meta_window_get_frame_rect (parent, &parent_rect); | ||||
|  | ||||
|   child_rect.x = parent_rect.x + (parent_rect.width / 2  - child_rect.width / 2); | ||||
|   child_rect.y = parent_rect.y + (parent_rect.height / 2 - child_rect.height / 2); | ||||
|   unextend_by_frame (window, &child_rect); | ||||
|   x = child_rect.x; | ||||
|   y = child_rect.y; | ||||
|  | ||||
|   constraint_already_satisfied = (x == info->current.x) && (y == info->current.y); | ||||
|  | ||||
| @@ -841,19 +806,19 @@ constrain_maximization (MetaWindow         *window, | ||||
|       active_workspace_struts = window->screen->active_workspace->all_struts; | ||||
|  | ||||
|       target_size = info->current; | ||||
|       extend_by_frame (&target_size, info->borders); | ||||
|       extend_by_frame (window, &target_size); | ||||
|       meta_rectangle_expand_to_avoiding_struts (&target_size, | ||||
|                                                 &info->entire_monitor, | ||||
|                                                 direction, | ||||
|                                                 active_workspace_struts); | ||||
|    } | ||||
|   /* Now make target_size = maximized size of client window */ | ||||
|   unextend_by_frame (&target_size, info->borders); | ||||
|   unextend_by_frame (window, &target_size); | ||||
|  | ||||
|   /* Check min size constraints; max size constraints are ignored for maximized | ||||
|    * windows, as per bug 327543. | ||||
|    */ | ||||
|   get_size_limits (window, info->borders, FALSE, &min_size, &max_size); | ||||
|   get_size_limits (window, FALSE, &min_size, &max_size); | ||||
|   hminbad = target_size.width < min_size.width && window->maximized_horizontally; | ||||
|   vminbad = target_size.height < min_size.height && window->maximized_vertically; | ||||
|   if (hminbad || vminbad) | ||||
| @@ -907,12 +872,12 @@ constrain_tiling (MetaWindow         *window, | ||||
|    * use an external function for the actual calculation | ||||
|    */ | ||||
|   meta_window_get_current_tile_area (window, &target_size); | ||||
|   unextend_by_frame (&target_size, info->borders); | ||||
|   unextend_by_frame (window, &target_size); | ||||
|  | ||||
|   /* Check min size constraints; max size constraints are ignored as for | ||||
|    * maximized windows. | ||||
|    */ | ||||
|   get_size_limits (window, info->borders, FALSE, &min_size, &max_size); | ||||
|   get_size_limits (window, FALSE, &min_size, &max_size); | ||||
|   hminbad = target_size.width < min_size.width; | ||||
|   vminbad = target_size.height < min_size.height; | ||||
|   if (hminbad || vminbad) | ||||
| @@ -955,7 +920,7 @@ constrain_fullscreen (MetaWindow         *window, | ||||
|  | ||||
|   monitor = info->entire_monitor; | ||||
|  | ||||
|   get_size_limits (window, info->borders, FALSE, &min_size, &max_size); | ||||
|   get_size_limits (window, FALSE, &min_size, &max_size); | ||||
|   too_big =   !meta_rectangle_could_fit_rect (&monitor, &min_size); | ||||
|   too_small = !meta_rectangle_could_fit_rect (&max_size, &monitor); | ||||
|   if (too_big || too_small) | ||||
| @@ -1064,7 +1029,7 @@ constrain_size_limits (MetaWindow         *window, | ||||
|     return TRUE; | ||||
|  | ||||
|   /* Determine whether constraint is already satisfied; exit if it is */ | ||||
|   get_size_limits (window, info->borders, FALSE, &min_size, &max_size); | ||||
|   get_size_limits (window, FALSE, &min_size, &max_size); | ||||
|   /* We ignore max-size limits for maximized windows; see #327543 */ | ||||
|   if (window->maximized_horizontally) | ||||
|     max_size.width = MAX (max_size.width, info->current.width); | ||||
| @@ -1256,8 +1221,8 @@ do_screen_and_monitor_relative_constraints ( | ||||
|  | ||||
|   /* Determine whether constraint applies; exit if it doesn't */ | ||||
|   how_far_it_can_be_smushed = info->current; | ||||
|   get_size_limits (window, info->borders, TRUE, &min_size, &max_size); | ||||
|   extend_by_frame (&info->current, info->borders); | ||||
|   get_size_limits (window, TRUE, &min_size, &max_size); | ||||
|   extend_by_frame (window, &info->current); | ||||
|  | ||||
|   if (info->action_type != ACTION_MOVE) | ||||
|     { | ||||
| @@ -1277,7 +1242,7 @@ do_screen_and_monitor_relative_constraints ( | ||||
|                                         &info->current); | ||||
|   if (exit_early || constraint_satisfied || check_only) | ||||
|     { | ||||
|       unextend_by_frame (&info->current, info->borders); | ||||
|       unextend_by_frame (window, &info->current); | ||||
|       return constraint_satisfied; | ||||
|     } | ||||
|  | ||||
| @@ -1301,7 +1266,7 @@ do_screen_and_monitor_relative_constraints ( | ||||
|                                       info->fixed_directions, | ||||
|                                       &info->current); | ||||
|  | ||||
|   unextend_by_frame (&info->current, info->borders); | ||||
|   unextend_by_frame (window, &info->current); | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| @@ -1414,8 +1379,11 @@ constrain_titlebar_visible (MetaWindow         *window, | ||||
|    */ | ||||
|   if (window->frame) | ||||
|     { | ||||
|       bottom_amount = info->current.height + info->borders->visible.bottom; | ||||
|       vert_amount_onscreen = info->borders->visible.top; | ||||
|       MetaFrameBorders borders; | ||||
|       meta_frame_calc_borders (window->frame, &borders); | ||||
|  | ||||
|       bottom_amount = info->current.height + borders.visible.bottom; | ||||
|       vert_amount_onscreen = borders.visible.top; | ||||
|     } | ||||
|   else | ||||
|     bottom_amount = vert_amount_offscreen; | ||||
| @@ -1489,8 +1457,11 @@ constrain_partially_onscreen (MetaWindow         *window, | ||||
|    */ | ||||
|   if (window->frame) | ||||
|     { | ||||
|       bottom_amount = info->current.height + info->borders->visible.bottom; | ||||
|       vert_amount_onscreen = info->borders->visible.top; | ||||
|       MetaFrameBorders borders; | ||||
|       meta_frame_calc_borders (window->frame, &borders); | ||||
|  | ||||
|       bottom_amount = info->current.height + borders.visible.bottom; | ||||
|       vert_amount_onscreen = borders.visible.top; | ||||
|     } | ||||
|   else | ||||
|     bottom_amount = vert_amount_offscreen; | ||||
|   | ||||
| @@ -39,7 +39,6 @@ typedef enum | ||||
| } MetaMoveResizeFlags; | ||||
|  | ||||
| void meta_window_constrain (MetaWindow          *window, | ||||
|                             MetaFrameBorders    *orig_borders, | ||||
|                             MetaMoveResizeFlags  flags, | ||||
|                             int                  resize_gravity, | ||||
|                             const MetaRectangle *orig, | ||||
|   | ||||
| @@ -171,6 +171,7 @@ meta_core_queue_frame_resize (Display *xdisplay, | ||||
|   MetaWindow *window = get_window (xdisplay, frame_xwindow); | ||||
|  | ||||
|   meta_window_queue (window, META_QUEUE_MOVE_RESIZE); | ||||
|   meta_window_frame_size_changed (window); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -279,8 +280,7 @@ meta_core_lower_beneath_grab_window (Display *xdisplay, | ||||
|     return; | ||||
|  | ||||
|   changes.stack_mode = Below; | ||||
|   changes.sibling = grab_window->frame ? grab_window->frame->xwindow | ||||
|                                        : grab_window->xwindow; | ||||
|   changes.sibling = meta_window_get_toplevel_xwindow (grab_window); | ||||
|  | ||||
|   meta_stack_tracker_record_lower_below (screen->stack_tracker, | ||||
|                                          xwindow, | ||||
|   | ||||
| @@ -117,12 +117,6 @@ typedef struct | ||||
|   guint        ping_timeout_id; | ||||
| } MetaPingData; | ||||
|  | ||||
| typedef struct  | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   Window xwindow; | ||||
| } MetaAutoRaiseData; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   MetaDisplay *display; | ||||
| @@ -1585,23 +1579,10 @@ reset_ignored_crossing_serials (MetaDisplay *display) | ||||
| static gboolean  | ||||
| window_raise_with_delay_callback (void *data) | ||||
| { | ||||
|   MetaWindow *window; | ||||
|   MetaAutoRaiseData *auto_raise; | ||||
|   MetaWindow *window = data; | ||||
|  | ||||
|   auto_raise = data; | ||||
|  | ||||
|   meta_topic (META_DEBUG_FOCUS,  | ||||
| 	      "In autoraise callback for window 0x%lx\n",  | ||||
| 	      auto_raise->xwindow); | ||||
|  | ||||
|   auto_raise->display->autoraise_timeout_id = 0; | ||||
|   auto_raise->display->autoraise_window = NULL; | ||||
|  | ||||
|   window  = meta_display_lookup_x_window (auto_raise->display,  | ||||
| 					  auto_raise->xwindow); | ||||
|    | ||||
|   if (window == NULL)  | ||||
|     return FALSE; | ||||
|   window->display->autoraise_timeout_id = 0; | ||||
|   window->display->autoraise_window = NULL; | ||||
|  | ||||
|   /* If we aren't already on top, check whether the pointer is inside | ||||
|    * the window and raise the window if so. | ||||
| @@ -1610,6 +1591,7 @@ window_raise_with_delay_callback (void *data) | ||||
|     { | ||||
|       int x, y, root_x, root_y; | ||||
|       Window root, child; | ||||
|       MetaRectangle frame_rect; | ||||
|       unsigned int mask; | ||||
|       gboolean same_screen; | ||||
|       gboolean point_in_window; | ||||
| @@ -1621,9 +1603,8 @@ window_raise_with_delay_callback (void *data) | ||||
| 				   &root_x, &root_y, &x, &y, &mask); | ||||
|       meta_error_trap_pop (window->display); | ||||
|  | ||||
|       point_in_window =  | ||||
|         (window->frame && POINT_IN_RECT (root_x, root_y, window->frame->rect)) || | ||||
|         (window->frame == NULL && POINT_IN_RECT (root_x, root_y, window->rect)); | ||||
|       meta_window_get_frame_rect (window, &frame_rect); | ||||
|       point_in_window = POINT_IN_RECT (root_x, root_y, frame_rect); | ||||
|       if (same_screen && point_in_window) | ||||
| 	meta_window_raise (window); | ||||
|       else | ||||
| @@ -1743,17 +1724,11 @@ void | ||||
| meta_display_queue_autoraise_callback (MetaDisplay *display, | ||||
|                                        MetaWindow  *window) | ||||
| { | ||||
|   MetaAutoRaiseData *auto_raise_data; | ||||
|  | ||||
|   meta_topic (META_DEBUG_FOCUS,  | ||||
|               "Queuing an autoraise timeout for %s with delay %d\n",  | ||||
|               window->desc,  | ||||
|               meta_prefs_get_auto_raise_delay ()); | ||||
|    | ||||
|   auto_raise_data = g_new (MetaAutoRaiseData, 1); | ||||
|   auto_raise_data->display = window->display; | ||||
|   auto_raise_data->xwindow = window->xwindow; | ||||
|    | ||||
|   if (display->autoraise_timeout_id != 0) | ||||
|     g_source_remove (display->autoraise_timeout_id); | ||||
|  | ||||
| @@ -1761,8 +1736,7 @@ meta_display_queue_autoraise_callback (MetaDisplay *display, | ||||
|     g_timeout_add_full (G_PRIORITY_DEFAULT, | ||||
|                         meta_prefs_get_auto_raise_delay (), | ||||
|                         window_raise_with_delay_callback, | ||||
|                         auto_raise_data, | ||||
|                         g_free); | ||||
|                         window, NULL); | ||||
|   display->autoraise_window = window; | ||||
| } | ||||
|  | ||||
| @@ -2127,6 +2101,19 @@ handle_window_focus_event (MetaDisplay  *display, | ||||
|     } | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| window_has_xwindow (MetaWindow *window, | ||||
|                     Window      xwindow) | ||||
| { | ||||
|   if (window->xwindow == xwindow) | ||||
|     return TRUE; | ||||
|  | ||||
|   if (window->frame && window->frame->xwindow == xwindow) | ||||
|     return TRUE; | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * event_callback: | ||||
|  * @event: The event that just happened | ||||
| @@ -2182,7 +2169,7 @@ event_callback (XEvent   *event, | ||||
|  | ||||
|   if (event->xany.serial > display->focus_serial && | ||||
|       display->focus_window && | ||||
|       display->focus_window->xwindow != display->server_focus_window) | ||||
|       !window_has_xwindow (display->focus_window, display->server_focus_window)) | ||||
|     { | ||||
|       meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n", | ||||
|                   display->focus_window->desc); | ||||
| @@ -2305,7 +2292,7 @@ event_callback (XEvent   *event, | ||||
|       XIEnterEvent *enter_event = (XIEnterEvent *) input_event; | ||||
|  | ||||
|       if (window && !window->override_redirect && | ||||
|           ((input_event->type == XI_KeyPress) || (input_event->type == XI_ButtonPress))) | ||||
|           ((input_event->evtype == XI_KeyPress) || (input_event->evtype == XI_ButtonPress))) | ||||
|         { | ||||
|           if (CurrentTime == display->current_time) | ||||
|             { | ||||
| @@ -2437,15 +2424,15 @@ event_callback (XEvent   *event, | ||||
|                     { | ||||
|                       gboolean north, south; | ||||
|                       gboolean west, east; | ||||
|                       int root_x, root_y; | ||||
|                       MetaRectangle frame_rect; | ||||
|                       MetaGrabOp op; | ||||
|  | ||||
|                       meta_window_get_position (window, &root_x, &root_y); | ||||
|                       meta_window_get_frame_rect (window, &frame_rect); | ||||
|  | ||||
|                       west = device_event->root_x <  (root_x + 1 * window->rect.width  / 3); | ||||
|                       east = device_event->root_x >  (root_x + 2 * window->rect.width  / 3); | ||||
|                       north = device_event->root_y < (root_y + 1 * window->rect.height / 3); | ||||
|                       south = device_event->root_y > (root_y + 2 * window->rect.height / 3); | ||||
|                       west = device_event->root_x <  (frame_rect.x + 1 * frame_rect.width  / 3); | ||||
|                       east = device_event->root_x >  (frame_rect.x + 2 * frame_rect.width  / 3); | ||||
|                       north = device_event->root_y < (frame_rect.y + 1 * frame_rect.height / 3); | ||||
|                       south = device_event->root_y > (frame_rect.y + 2 * frame_rect.height / 3); | ||||
|  | ||||
|                       if (north && west) | ||||
|                         op = META_GRAB_OP_RESIZING_NW; | ||||
| @@ -4021,7 +4008,7 @@ meta_display_begin_grab_op (MetaDisplay *display, | ||||
|    *   key grab on the RootWindow. | ||||
|    */ | ||||
|   if (grab_window) | ||||
|     grab_xwindow = grab_window->frame ? grab_window->frame->xwindow : grab_window->xwindow; | ||||
|     grab_xwindow = meta_window_get_toplevel_xwindow (grab_window); | ||||
|   else | ||||
|     grab_xwindow = screen->xroot; | ||||
|  | ||||
| @@ -4549,6 +4536,7 @@ meta_display_queue_retheme_all_windows (MetaDisplay *display) | ||||
|       MetaWindow *window = tmp->data; | ||||
|        | ||||
|       meta_window_queue (window, META_QUEUE_MOVE_RESIZE); | ||||
|       meta_window_frame_size_changed (window); | ||||
|       if (window->frame) | ||||
|         { | ||||
|           meta_frame_queue_draw (window->frame); | ||||
|   | ||||
| @@ -985,7 +985,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) | ||||
|         { | ||||
|           MetaRectangle *new_rect; | ||||
|           new_rect = g_new (MetaRectangle, 1); | ||||
|           meta_window_get_outer_rect (cur_window, new_rect); | ||||
|           meta_window_get_frame_rect (cur_window, new_rect); | ||||
|           obscuring_windows = g_slist_prepend (obscuring_windows, new_rect); | ||||
|           window_stacking =  | ||||
|             g_slist_prepend (window_stacking, GINT_TO_POINTER (stack_position)); | ||||
| @@ -1010,7 +1010,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) | ||||
|     { | ||||
|       MetaRectangle  cur_rect; | ||||
|       MetaWindow    *cur_window = cur_window_iter->data; | ||||
|       meta_window_get_outer_rect (cur_window, &cur_rect); | ||||
|       meta_window_get_frame_rect (cur_window, &cur_rect); | ||||
|  | ||||
|       /* Check if we want to use this window's edges for edge | ||||
|        * resistance (note that dock edges are considered screen edges | ||||
| @@ -1151,7 +1151,7 @@ meta_window_edge_resistance_for_move (MetaWindow  *window, | ||||
|   MetaRectangle old_outer, proposed_outer, new_outer; | ||||
|   gboolean is_resize; | ||||
|  | ||||
|   meta_window_get_outer_rect (window, &old_outer); | ||||
|   meta_window_get_frame_rect (window, &old_outer); | ||||
|  | ||||
|   proposed_outer = old_outer; | ||||
|   proposed_outer.x += (*new_x - old_x); | ||||
| @@ -1237,7 +1237,7 @@ meta_window_edge_resistance_for_resize (MetaWindow  *window, | ||||
|   int proposed_outer_width, proposed_outer_height; | ||||
|   gboolean is_resize; | ||||
|  | ||||
|   meta_window_get_outer_rect (window, &old_outer); | ||||
|   meta_window_get_frame_rect (window, &old_outer); | ||||
|   proposed_outer_width  = old_outer.width  + (*new_width  - old_width); | ||||
|   proposed_outer_height = old_outer.height + (*new_height - old_height); | ||||
|   meta_rectangle_resize_with_gravity (&old_outer,  | ||||
|   | ||||
| @@ -68,6 +68,7 @@ meta_window_ensure_frame (MetaWindow *window) | ||||
|  | ||||
|   frame->mapped = FALSE; | ||||
|   frame->is_flashing = FALSE; | ||||
|   frame->borders_cached = FALSE; | ||||
|    | ||||
|   meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n", | ||||
|                 window->desc, | ||||
| @@ -327,9 +328,23 @@ meta_frame_calc_borders (MetaFrame        *frame, | ||||
|   if (frame == NULL) | ||||
|     meta_frame_borders_clear (borders); | ||||
|   else | ||||
|     meta_ui_get_frame_borders (frame->window->screen->ui, | ||||
|                                frame->xwindow, | ||||
|                                borders); | ||||
|     { | ||||
|       if (!frame->borders_cached) | ||||
|         { | ||||
|           meta_ui_get_frame_borders (frame->window->screen->ui, | ||||
|                                      frame->xwindow, | ||||
|                                      &frame->cached_borders); | ||||
|           frame->borders_cached = TRUE; | ||||
|         } | ||||
|  | ||||
|       *borders = frame->cached_borders; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_frame_clear_cached_borders (MetaFrame *frame) | ||||
| { | ||||
|   frame->borders_cached = FALSE; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
|   | ||||
| @@ -41,6 +41,8 @@ struct _MetaFrame | ||||
|    */ | ||||
|   MetaRectangle rect; | ||||
|  | ||||
|   MetaFrameBorders cached_borders; /* valid if borders_cached is set */ | ||||
|  | ||||
|   /* position of client, size of frame */ | ||||
|   int child_x; | ||||
|   int child_y; | ||||
| @@ -50,6 +52,7 @@ struct _MetaFrame | ||||
|   guint mapped : 1; | ||||
|   guint need_reapply_frame_shape : 1; | ||||
|   guint is_flashing : 1; /* used by the visual bell flash */ | ||||
|   guint borders_cached : 1; | ||||
| }; | ||||
|  | ||||
| void     meta_window_ensure_frame           (MetaWindow *window); | ||||
| @@ -68,6 +71,8 @@ gboolean meta_frame_sync_to_window (MetaFrame         *frame, | ||||
|                                     gboolean           need_move, | ||||
|                                     gboolean           need_resize); | ||||
|  | ||||
| void meta_frame_clear_cached_borders (MetaFrame *frame); | ||||
|  | ||||
| cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame); | ||||
|  | ||||
| void meta_frame_get_mask (MetaFrame *frame, | ||||
|   | ||||
| @@ -1277,7 +1277,7 @@ meta_window_grab_keys (MetaWindow  *window) | ||||
|     } | ||||
|  | ||||
|   meta_window_change_keygrabs (window, | ||||
|                                window->frame ? window->frame->xwindow : window->xwindow, | ||||
|                                meta_window_get_toplevel_xwindow (window), | ||||
|                                TRUE); | ||||
|  | ||||
|   window->keys_grabbed = TRUE; | ||||
| @@ -1580,7 +1580,7 @@ meta_window_grab_all_keys (MetaWindow  *window, | ||||
|               window->desc); | ||||
|   meta_window_focus (window, timestamp); | ||||
|  | ||||
|   grabwindow = window->frame ? window->frame->xwindow : window->xwindow; | ||||
|   grabwindow = meta_window_get_toplevel_xwindow (window); | ||||
|  | ||||
|   meta_topic (META_DEBUG_KEYBINDINGS, | ||||
|               "Grabbing all keys on window %s\n", window->desc); | ||||
| @@ -3137,6 +3137,20 @@ handle_maximize_horizontally (MetaDisplay    *display, | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| handle_always_on_top          (MetaDisplay    *display, | ||||
|                               MetaScreen     *screen, | ||||
|                               MetaWindow     *window, | ||||
|                               XIDeviceEvent  *event, | ||||
|                               MetaKeyBinding *binding, | ||||
|                               gpointer        dummy) | ||||
| { | ||||
|   if (window->wm_state_above == FALSE) | ||||
|     meta_window_make_above (window); | ||||
|   else | ||||
|     meta_window_unmake_above (window); | ||||
| } | ||||
|  | ||||
| /* Move a window to a corner; to_bottom/to_right are FALSE for the | ||||
|  * top or left edge, or TRUE for the bottom/right edge.  xchange/ychange | ||||
|  * are FALSE if that dimension is not to be changed, TRUE otherwise. | ||||
| @@ -3154,17 +3168,17 @@ handle_move_to_corner_backend (MetaDisplay    *display, | ||||
|                                gpointer        dummy) | ||||
| { | ||||
|   MetaRectangle work_area; | ||||
|   MetaRectangle outer; | ||||
|   MetaRectangle frame_rect; | ||||
|   int orig_x, orig_y; | ||||
|   int new_x, new_y; | ||||
|  | ||||
|   meta_window_get_work_area_all_monitors (window, &work_area); | ||||
|   meta_window_get_outer_rect (window, &outer); | ||||
|   meta_window_get_frame_rect (window, &frame_rect); | ||||
|   meta_window_get_position (window, &orig_x, &orig_y); | ||||
|  | ||||
|   if (xchange) { | ||||
|     new_x = work_area.x + (to_right ? | ||||
|                            work_area.width - outer.width : | ||||
|                            work_area.width - frame_rect.width : | ||||
|                            0); | ||||
|   } else { | ||||
|     new_x = orig_x; | ||||
| @@ -3172,7 +3186,7 @@ handle_move_to_corner_backend (MetaDisplay    *display, | ||||
|  | ||||
|   if (ychange) { | ||||
|     new_y = work_area.y + (to_bottom ? | ||||
|                            work_area.height - outer.height : | ||||
|                            work_area.height - frame_rect.height : | ||||
|                            0); | ||||
|   } else { | ||||
|     new_y = orig_y; | ||||
| @@ -3281,12 +3295,12 @@ handle_move_to_center  (MetaDisplay    *display, | ||||
|                         gpointer        dummy) | ||||
| { | ||||
|   MetaRectangle work_area; | ||||
|   MetaRectangle outer; | ||||
|   MetaRectangle frame_rect; | ||||
|   int orig_x, orig_y; | ||||
|   int frame_width, frame_height; | ||||
|  | ||||
|   meta_window_get_work_area_all_monitors (window, &work_area); | ||||
|   meta_window_get_outer_rect (window, &outer); | ||||
|   meta_window_get_frame_rect (window, &frame_rect); | ||||
|   meta_window_get_position (window, &orig_x, &orig_y); | ||||
|  | ||||
|   frame_width = (window->frame ? window->frame->child_x : 0); | ||||
| @@ -3294,8 +3308,8 @@ handle_move_to_center  (MetaDisplay    *display, | ||||
|  | ||||
|   meta_window_move_resize (window, | ||||
|                            TRUE, | ||||
|                            work_area.x + (work_area.width +frame_width -outer.width )/2, | ||||
|                            work_area.y + (work_area.height+frame_height-outer.height)/2, | ||||
|                            work_area.x + (work_area.width +frame_width -frame_rect.width )/2, | ||||
|                            work_area.y + (work_area.height+frame_height-frame_rect.height)/2, | ||||
|                            window->rect.width, | ||||
|                            window->rect.height); | ||||
| } | ||||
| @@ -3988,8 +4002,8 @@ handle_raise_or_lower (MetaDisplay    *display, | ||||
|  | ||||
|       if (above->mapped) | ||||
|         { | ||||
|           meta_window_get_outer_rect (window, &win_rect); | ||||
|           meta_window_get_outer_rect (above, &above_rect); | ||||
|           meta_window_get_frame_rect (window, &win_rect); | ||||
|           meta_window_get_frame_rect (above, &above_rect); | ||||
|  | ||||
|           /* Check if obscured */ | ||||
|           if (meta_rectangle_intersect (&win_rect, &above_rect, &tmp)) | ||||
| @@ -4650,6 +4664,13 @@ init_builtin_key_bindings (MetaDisplay *display) | ||||
|                           META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY, | ||||
|                           handle_maximize_horizontally, 0); | ||||
|  | ||||
|   add_builtin_keybinding (display, | ||||
|                           "always-on-top", | ||||
|                           common_keybindings, | ||||
|                           META_KEY_BINDING_PER_WINDOW, | ||||
|                           META_KEYBINDING_ACTION_ALWAYS_ON_TOP, | ||||
|                           handle_always_on_top, 0); | ||||
|  | ||||
|   add_builtin_keybinding (display, | ||||
|                           "move-to-corner-nw", | ||||
|                           common_keybindings, | ||||
|   | ||||
| @@ -842,6 +842,8 @@ on_bus_acquired (GDBusConnection *connection, | ||||
|   for (iter = devices; iter; iter = iter->next) | ||||
|     on_device_added (device_manager, iter->data, manager); | ||||
|  | ||||
|   g_slist_free (devices); | ||||
|  | ||||
|   g_signal_connect_object (device_manager, "device-added", | ||||
|                            G_CALLBACK (on_device_added), manager, 0); | ||||
|   g_signal_connect_object (device_manager, "device-removed", | ||||
|   | ||||
| @@ -817,6 +817,22 @@ meta_monitor_config_match_current (MetaMonitorConfig  *self, | ||||
|   return ok; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager) | ||||
| { | ||||
|   MetaOutput *outputs; | ||||
|   unsigned n_outputs; | ||||
|   unsigned int i; | ||||
|  | ||||
|   outputs = meta_monitor_manager_get_outputs (manager, &n_outputs); | ||||
|  | ||||
|   for (i = 0; i < n_outputs; i++) | ||||
|     if (outputs[i].hotplug_mode_update) | ||||
|       return TRUE; | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static MetaConfiguration * | ||||
| meta_monitor_config_get_stored (MetaMonitorConfig *self, | ||||
| 				MetaOutput        *outputs, | ||||
|   | ||||
| @@ -116,6 +116,9 @@ struct _MetaOutput | ||||
|   */ | ||||
|   gboolean is_primary; | ||||
|   gboolean is_presentation; | ||||
|  | ||||
|   /* get a new preferred mode on hotplug events, to handle dynamic guest resizing */ | ||||
|   gboolean hotplug_mode_update; | ||||
| }; | ||||
|  | ||||
| struct _MetaCRTC | ||||
| @@ -383,6 +386,7 @@ void               meta_output_info_free (MetaOutputInfo *info); | ||||
|  | ||||
| void               meta_monitor_manager_free_output_array (MetaOutput *old_outputs, | ||||
|                                                            int         n_old_outputs); | ||||
| gboolean           meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager); | ||||
|  | ||||
| /* Returns true if transform causes width and height to be inverted | ||||
|    This is true for the odd transforms in the enum */ | ||||
|   | ||||
| @@ -311,6 +311,29 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr, | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr, | ||||
|                                 XID                       output_id) | ||||
| { | ||||
|   MetaDisplay *display = meta_get_display (); | ||||
|   XRRPropertyInfo *info; | ||||
|   gboolean result = FALSE; | ||||
|  | ||||
|   meta_error_trap_push (display); | ||||
|   info = XRRQueryOutputProperty (manager_xrandr->xdisplay, output_id, | ||||
|                                  display->atom_hotplug_mode_update); | ||||
|   meta_error_trap_pop (display); | ||||
|  | ||||
|   if (info) | ||||
|     { | ||||
|       result = TRUE; | ||||
|       XFree (info); | ||||
|     } | ||||
|  | ||||
|   return result; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void | ||||
| meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) | ||||
| { | ||||
| @@ -430,8 +453,10 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) | ||||
|       XRRFreeCrtcInfo (crtc); | ||||
|     } | ||||
|  | ||||
|   meta_error_trap_push (meta_get_display ()); | ||||
|   primary_output = XRRGetOutputPrimary (manager_xrandr->xdisplay, | ||||
| 					DefaultRootWindow (manager_xrandr->xdisplay)); | ||||
|   meta_error_trap_pop (meta_get_display ()); | ||||
|  | ||||
|   n_actual_outputs = 0; | ||||
|   for (i = 0; i < (unsigned)resources->noutput; i++) | ||||
| @@ -484,6 +509,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) | ||||
| 	  meta_output->width_mm = output->mm_width; | ||||
| 	  meta_output->height_mm = output->mm_height; | ||||
| 	  meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; | ||||
|           meta_output->hotplug_mode_update = | ||||
|               output_get_hotplug_mode_update (manager_xrandr, meta_output->output_id); | ||||
|  | ||||
| 	  meta_output->n_modes = output->nmode; | ||||
| 	  meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes); | ||||
| @@ -668,10 +695,11 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
| 						 unsigned int         n_outputs) | ||||
| { | ||||
|   MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager); | ||||
|   MetaDisplay *display = meta_get_display (); | ||||
|   unsigned i; | ||||
|   int width, height, width_mm, height_mm; | ||||
|  | ||||
|   meta_display_grab (meta_get_display ()); | ||||
|   meta_display_grab (display); | ||||
|  | ||||
|   /* First compute the new size of the screen (framebuffer) */ | ||||
|   width = 0; height = 0; | ||||
| @@ -765,10 +793,10 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
|    */ | ||||
|   width_mm = (width / DPI_FALLBACK) * 25.4 + 0.5; | ||||
|   height_mm = (height / DPI_FALLBACK) * 25.4 + 0.5; | ||||
|   meta_error_trap_push (meta_get_display ()); | ||||
|   meta_error_trap_push (display); | ||||
|   XRRSetScreenSize (manager_xrandr->xdisplay, DefaultRootWindow (manager_xrandr->xdisplay), | ||||
|                     width, height, width_mm, height_mm); | ||||
|   meta_error_trap_pop (meta_get_display ()); | ||||
|   meta_error_trap_pop (display); | ||||
|  | ||||
|   for (i = 0; i < n_crtcs; i++) | ||||
|     { | ||||
| @@ -825,7 +853,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
|               goto next; | ||||
|             } | ||||
|  | ||||
|           meta_error_trap_push (meta_get_display ()); | ||||
|           meta_error_trap_push (display); | ||||
|           ok = XRRSetCrtcConfig (manager_xrandr->xdisplay, | ||||
|                                  manager_xrandr->resources, | ||||
|                                  (XID)crtc->crtc_id, | ||||
| @@ -834,7 +862,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
|                                  (XID)mode->mode_id, | ||||
|                                  wl_transform_to_xrandr (crtc_info->transform), | ||||
|                                  outputs, n_outputs); | ||||
|           meta_error_trap_pop (meta_get_display ()); | ||||
|           meta_error_trap_pop (display); | ||||
|  | ||||
|           if (ok != Success) | ||||
|             { | ||||
| @@ -875,9 +903,11 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
|  | ||||
|       if (output_info->is_primary) | ||||
|         { | ||||
|           meta_error_trap_push (display); | ||||
|           XRRSetOutputPrimary (manager_xrandr->xdisplay, | ||||
|                                DefaultRootWindow (manager_xrandr->xdisplay), | ||||
|                                (XID)output_info->output->output_id); | ||||
|           meta_error_trap_pop (display); | ||||
|         } | ||||
|  | ||||
|       output_set_presentation_xrandr (manager_xrandr, | ||||
| @@ -903,7 +933,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
|       output->is_primary = FALSE; | ||||
|     } | ||||
|  | ||||
|   meta_display_ungrab (meta_get_display ()); | ||||
|   meta_display_ungrab (display); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -971,6 +1001,16 @@ meta_monitor_manager_xrandr_set_crtc_gamma (MetaMonitorManager *manager, | ||||
|   XRRFreeGamma (gamma); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_monitor_manager_xrandr_rebuild_derived (MetaMonitorManager *manager) | ||||
| { | ||||
|   /* This will be a no-op if the change was from our side, as | ||||
|      we already called it in the DBus method handler */ | ||||
|   meta_monitor_config_update_current (manager->config, manager); | ||||
|  | ||||
|   meta_monitor_manager_rebuild_derived (manager); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager, | ||||
| 					   XEvent             *event) | ||||
| @@ -980,6 +1020,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager, | ||||
|   MetaCRTC *old_crtcs; | ||||
|   MetaMonitorMode *old_modes; | ||||
|   int n_old_outputs; | ||||
|   gboolean new_config; | ||||
|  | ||||
|   if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify) | ||||
|     return FALSE; | ||||
| @@ -995,31 +1036,36 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager, | ||||
|   manager->serial++; | ||||
|   meta_monitor_manager_xrandr_read_current (manager); | ||||
|  | ||||
|   /* Check if the current intended configuration has the same outputs | ||||
|      as the new real one, or if the event is a result of an XRandR call. | ||||
|      If so, we can go straight to rebuild the logical config and tell | ||||
|      the outside world. | ||||
|      Otherwise, this event was caused by hotplug, so give a chance to | ||||
|      MetaMonitorConfig. | ||||
|   new_config = manager_xrandr->resources->timestamp >= | ||||
|     manager_xrandr->resources->configTimestamp; | ||||
|   if (meta_monitor_manager_has_hotplug_mode_update (manager)) | ||||
|  | ||||
|      Note that we need to check both the timestamps and the list of | ||||
|      outputs, because the X server might emit spurious events with | ||||
|      new configTimestamps (bug 702804), and the driver may have | ||||
|      changed the EDID for some other reason (old broken qxl and vbox | ||||
|      drivers...). | ||||
|   */ | ||||
|   if (manager_xrandr->resources->timestamp >= manager_xrandr->resources->configTimestamp || | ||||
|       meta_monitor_config_match_current (manager->config, manager)) | ||||
|     { | ||||
|       /* This will be a no-op if the change was from our side, as | ||||
|          we already called it in the DBus method handler */ | ||||
|       meta_monitor_config_update_current (manager->config, manager); | ||||
|  | ||||
|       meta_monitor_manager_rebuild_derived (manager); | ||||
|       /* Check if the current intended configuration is a result of an | ||||
|          XRandR call.  Otherwise, hotplug_mode_update tells us to get | ||||
|          a new preferred mode on hotplug events to handle dynamic | ||||
|          guest resizing. */ | ||||
|       if (new_config) | ||||
|         meta_monitor_manager_xrandr_rebuild_derived (manager); | ||||
|       else | ||||
|         meta_monitor_config_make_default (manager->config, manager); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if (!meta_monitor_config_apply_stored (manager->config, manager)) | ||||
|       /* Check if the current intended configuration has the same outputs | ||||
|          as the new real one, or if the event is a result of an XRandR call. | ||||
|          If so, we can go straight to rebuild the logical config and tell | ||||
|          the outside world. | ||||
|          Otherwise, this event was caused by hotplug, so give a chance to | ||||
|          MetaMonitorConfig. | ||||
|  | ||||
|          Note that we need to check both the timestamps and the list of | ||||
|          outputs, because the X server might emit spurious events with new | ||||
|          configTimestamps (bug 702804), and the driver may have changed | ||||
|          the EDID for some other reason (old qxl and vbox drivers). */ | ||||
|       if (new_config || meta_monitor_config_match_current (manager->config, manager)) | ||||
|         meta_monitor_manager_xrandr_rebuild_derived (manager); | ||||
|       else if (!meta_monitor_config_apply_stored (manager->config, manager)) | ||||
|         meta_monitor_config_make_default (manager->config, manager); | ||||
|     } | ||||
|  | ||||
|   | ||||
							
								
								
									
										299
									
								
								src/core/place.c
									
									
									
									
									
								
							
							
						
						
									
										299
									
								
								src/core/place.c
									
									
									
									
									
								
							| @@ -47,34 +47,18 @@ northwestcmp (gconstpointer a, gconstpointer b) | ||||
| { | ||||
|   MetaWindow *aw = (gpointer) a; | ||||
|   MetaWindow *bw = (gpointer) b; | ||||
|   MetaRectangle a_frame; | ||||
|   MetaRectangle b_frame; | ||||
|   int from_origin_a; | ||||
|   int from_origin_b; | ||||
|   int ax, ay, bx, by; | ||||
|  | ||||
|   /* we're interested in the frame position for cascading, | ||||
|    * not meta_window_get_position() | ||||
|    */ | ||||
|   if (aw->frame) | ||||
|     { | ||||
|       ax = aw->frame->rect.x; | ||||
|       ay = aw->frame->rect.y; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       ax = aw->rect.x; | ||||
|       ay = aw->rect.y; | ||||
|     } | ||||
|  | ||||
|   if (bw->frame) | ||||
|     { | ||||
|       bx = bw->frame->rect.x; | ||||
|       by = bw->frame->rect.y; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       bx = bw->rect.x; | ||||
|       by = bw->rect.y; | ||||
|     } | ||||
|   meta_window_get_frame_rect (aw, &a_frame); | ||||
|   meta_window_get_frame_rect (bw, &b_frame); | ||||
|   ax = a_frame.x; | ||||
|   ay = a_frame.y; | ||||
|   bx = b_frame.x; | ||||
|   by = b_frame.y; | ||||
|    | ||||
|   /* probably there's a fast good-enough-guess we could use here. */ | ||||
|   from_origin_a = sqrt (ax * ax + ay * ay); | ||||
| @@ -90,7 +74,6 @@ northwestcmp (gconstpointer a, gconstpointer b) | ||||
|  | ||||
| static void | ||||
| find_next_cascade (MetaWindow *window, | ||||
|                    MetaFrameBorders *borders, | ||||
|                    /* visible windows on relevant workspaces */ | ||||
|                    GList      *windows, | ||||
|                    int         x, | ||||
| @@ -102,6 +85,7 @@ find_next_cascade (MetaWindow *window, | ||||
|   GList *sorted; | ||||
|   int cascade_x, cascade_y; | ||||
|   int x_threshold, y_threshold; | ||||
|   MetaRectangle frame_rect; | ||||
|   int window_width, window_height; | ||||
|   int cascade_stage; | ||||
|   MetaRectangle work_area; | ||||
| @@ -120,10 +104,13 @@ find_next_cascade (MetaWindow *window, | ||||
|    * manually cascade. | ||||
|    */ | ||||
| #define CASCADE_FUZZ 15 | ||||
|   if (borders) | ||||
|   if (window->frame) | ||||
|     { | ||||
|       x_threshold = MAX (borders->visible.left, CASCADE_FUZZ); | ||||
|       y_threshold = MAX (borders->visible.top, CASCADE_FUZZ); | ||||
|       MetaFrameBorders borders; | ||||
|  | ||||
|       meta_frame_calc_borders (window->frame, &borders); | ||||
|       x_threshold = MAX (borders.visible.left, CASCADE_FUZZ); | ||||
|       y_threshold = MAX (borders.visible.top, CASCADE_FUZZ); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
| @@ -143,30 +130,25 @@ find_next_cascade (MetaWindow *window, | ||||
|   cascade_y = MAX (0, work_area.y); | ||||
|    | ||||
|   /* Find first cascade position that's not used. */ | ||||
|    | ||||
|   window_width = window->frame ? window->frame->rect.width : window->rect.width; | ||||
|   window_height = window->frame ? window->frame->rect.height : window->rect.height; | ||||
|  | ||||
|   meta_window_get_frame_rect (window, &frame_rect); | ||||
|   window_width = frame_rect.width; | ||||
|   window_height = frame_rect.height; | ||||
|    | ||||
|   cascade_stage = 0; | ||||
|   tmp = sorted; | ||||
|   while (tmp != NULL) | ||||
|     { | ||||
|       MetaWindow *w; | ||||
|       MetaRectangle w_frame_rect; | ||||
|       int wx, wy; | ||||
|        | ||||
|       w = tmp->data; | ||||
|  | ||||
|       /* we want frame position, not window position */ | ||||
|       if (w->frame) | ||||
|         { | ||||
|           wx = w->frame->rect.x; | ||||
|           wy = w->frame->rect.y; | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           wx = w->rect.x; | ||||
|           wy = w->rect.y; | ||||
|         } | ||||
|       meta_window_get_frame_rect (w, &w_frame_rect); | ||||
|       wx = w_frame_rect.x; | ||||
|       wy = w_frame_rect.y; | ||||
|        | ||||
|       if (ABS (wx - cascade_x) < x_threshold && | ||||
|           ABS (wy - cascade_y) < y_threshold) | ||||
| @@ -223,22 +205,12 @@ find_next_cascade (MetaWindow *window, | ||||
|    | ||||
|   g_list_free (sorted); | ||||
|  | ||||
|   /* Convert coords to position of window, not position of frame. */ | ||||
|   if (borders == NULL) | ||||
|     { | ||||
|       *new_x = cascade_x; | ||||
|       *new_y = cascade_y; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       *new_x = cascade_x + borders->visible.left; | ||||
|       *new_y = cascade_y + borders->visible.top; | ||||
|     } | ||||
|   *new_x = cascade_x; | ||||
|   *new_y = cascade_y; | ||||
| } | ||||
|  | ||||
| static void | ||||
| find_most_freespace (MetaWindow *window, | ||||
|                      MetaFrameBorders *borders, | ||||
|                      /* visible windows on relevant workspaces */ | ||||
|                      MetaWindow *focus_window, | ||||
|                      int         x, | ||||
| @@ -250,29 +222,25 @@ find_most_freespace (MetaWindow *window, | ||||
|   int max_area; | ||||
|   int max_width, max_height, left, right, top, bottom; | ||||
|   int left_space, right_space, top_space, bottom_space; | ||||
|   int frame_size_left, frame_size_top; | ||||
|   MetaRectangle work_area; | ||||
|   MetaRectangle avoid; | ||||
|   MetaRectangle outer; | ||||
|  | ||||
|   frame_size_left = borders ? borders->visible.left : 0; | ||||
|   frame_size_top  = borders ? borders->visible.top : 0; | ||||
|   MetaRectangle frame_rect; | ||||
|  | ||||
|   meta_window_get_work_area_current_monitor (focus_window, &work_area); | ||||
|   meta_window_get_outer_rect (focus_window, &avoid); | ||||
|   meta_window_get_outer_rect (window, &outer); | ||||
|   meta_window_get_frame_rect (focus_window, &avoid); | ||||
|   meta_window_get_frame_rect (window, &frame_rect); | ||||
|  | ||||
|   /* Find the areas of choosing the various sides of the focus window */ | ||||
|   max_width  = MIN (avoid.width, outer.width); | ||||
|   max_height = MIN (avoid.height, outer.height); | ||||
|   max_width  = MIN (avoid.width, frame_rect.width); | ||||
|   max_height = MIN (avoid.height, frame_rect.height); | ||||
|   left_space   = avoid.x - work_area.x; | ||||
|   right_space  = work_area.width - (avoid.x + avoid.width - work_area.x); | ||||
|   top_space    = avoid.y - work_area.y; | ||||
|   bottom_space = work_area.height - (avoid.y + avoid.height - work_area.y); | ||||
|   left   = MIN (left_space,   outer.width); | ||||
|   right  = MIN (right_space,  outer.width); | ||||
|   top    = MIN (top_space,    outer.height); | ||||
|   bottom = MIN (bottom_space, outer.height); | ||||
|   left   = MIN (left_space,   frame_rect.width); | ||||
|   right  = MIN (right_space,  frame_rect.width); | ||||
|   top    = MIN (top_space,    frame_rect.height); | ||||
|   bottom = MIN (bottom_space, frame_rect.height); | ||||
|  | ||||
|   /* Find out which side of the focus_window can show the most of the window */ | ||||
|   side = META_LEFT; | ||||
| @@ -304,39 +272,56 @@ find_most_freespace (MetaWindow *window, | ||||
|   switch (side) | ||||
|     { | ||||
|     case META_LEFT: | ||||
|       *new_y = avoid.y + frame_size_top; | ||||
|       if (left_space > outer.width) | ||||
|         *new_x = avoid.x - outer.width + frame_size_left; | ||||
|       *new_y = avoid.y; | ||||
|       if (left_space > frame_rect.width) | ||||
|         *new_x = avoid.x - frame_rect.width; | ||||
|       else | ||||
|         *new_x = work_area.x + frame_size_left; | ||||
|         *new_x = work_area.x; | ||||
|       break; | ||||
|     case META_RIGHT: | ||||
|       *new_y = avoid.y + frame_size_top; | ||||
|       if (right_space > outer.width) | ||||
|         *new_x = avoid.x + avoid.width + frame_size_left; | ||||
|       *new_y = avoid.y; | ||||
|       if (right_space > frame_rect.width) | ||||
|         *new_x = avoid.x + avoid.width; | ||||
|       else | ||||
|         *new_x = work_area.x + work_area.width - outer.width + frame_size_left; | ||||
|         *new_x = work_area.x + work_area.width - frame_rect.width; | ||||
|       break; | ||||
|     case META_TOP: | ||||
|       *new_x = avoid.x + frame_size_left; | ||||
|       if (top_space > outer.height) | ||||
|         *new_y = avoid.y - outer.height + frame_size_top; | ||||
|       *new_x = avoid.x; | ||||
|       if (top_space > frame_rect.height) | ||||
|         *new_y = avoid.y - frame_rect.height; | ||||
|       else | ||||
|         *new_y = work_area.y + frame_size_top; | ||||
|         *new_y = work_area.y; | ||||
|       break; | ||||
|     case META_BOTTOM: | ||||
|       *new_x = avoid.x + frame_size_left; | ||||
|       if (bottom_space > outer.height) | ||||
|         *new_y = avoid.y + avoid.height + frame_size_top; | ||||
|       *new_x = avoid.x; | ||||
|       if (bottom_space > frame_rect.height) | ||||
|         *new_y = avoid.y + avoid.height; | ||||
|       else | ||||
|         *new_y = work_area.y + work_area.height - outer.height + frame_size_top; | ||||
|         *new_y = work_area.y + work_area.height - frame_rect.height; | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| window_overlaps_focus_window (MetaWindow *window) | ||||
| { | ||||
|   MetaWindow *focus_window; | ||||
|   MetaRectangle window_frame, focus_frame, overlap; | ||||
|  | ||||
|   focus_window = window->display->focus_window; | ||||
|   if (focus_window == NULL) | ||||
|     return FALSE; | ||||
|  | ||||
|   meta_window_get_frame_rect (window, &window_frame); | ||||
|   meta_window_get_frame_rect (focus_window, &focus_frame); | ||||
|  | ||||
|   return meta_rectangle_intersect (&window_frame, | ||||
|                                    &focus_frame, | ||||
|                                    &overlap); | ||||
| } | ||||
|  | ||||
| static void | ||||
| avoid_being_obscured_as_second_modal_dialog (MetaWindow *window, | ||||
|                                              MetaFrameBorders *borders, | ||||
|                                              int        *x, | ||||
|                                              int        *y) | ||||
| { | ||||
| @@ -355,18 +340,17 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window, | ||||
|    */ | ||||
|  | ||||
|   MetaWindow *focus_window; | ||||
|   MetaRectangle overlap; | ||||
|  | ||||
|   focus_window = window->display->focus_window; | ||||
|  | ||||
|   /* denied_focus_and_not_transient is only set when focus_window != NULL */ | ||||
|  | ||||
|   if (window->denied_focus_and_not_transient && | ||||
|       window->wm_state_modal && /* FIXME: Maybe do this for all transients? */ | ||||
|       meta_window_same_application (window, focus_window) && | ||||
|       meta_rectangle_intersect (&window->rect, | ||||
|                                 &focus_window->rect, | ||||
|                                 &overlap)) | ||||
|       window_overlaps_focus_window (window)) | ||||
|     { | ||||
|       find_most_freespace (window, borders, focus_window, *x, *y, x, y); | ||||
|       find_most_freespace (window, focus_window, *x, *y, x, y); | ||||
|       meta_topic (META_DEBUG_PLACEMENT, | ||||
|                   "Dialog window %s was denied focus but may be modal " | ||||
|                   "to the focus window; had to move it to avoid the " | ||||
| @@ -409,7 +393,7 @@ rectangle_overlaps_some_window (MetaRectangle *rect, | ||||
|         case META_WINDOW_UTILITY: | ||||
|         case META_WINDOW_TOOLBAR: | ||||
|         case META_WINDOW_MENU: | ||||
|           meta_window_get_outer_rect (other, &other_rect); | ||||
|           meta_window_get_frame_rect (other, &other_rect); | ||||
|            | ||||
|           if (meta_rectangle_intersect (rect, &other_rect, &dest)) | ||||
|             return TRUE; | ||||
| @@ -427,20 +411,14 @@ leftmost_cmp (gconstpointer a, gconstpointer b) | ||||
| { | ||||
|   MetaWindow *aw = (gpointer) a; | ||||
|   MetaWindow *bw = (gpointer) b; | ||||
|   MetaRectangle a_frame; | ||||
|   MetaRectangle b_frame; | ||||
|   int ax, bx; | ||||
|  | ||||
|   /* we're interested in the frame position for cascading, | ||||
|    * not meta_window_get_position() | ||||
|    */ | ||||
|   if (aw->frame) | ||||
|     ax = aw->frame->rect.x; | ||||
|   else | ||||
|     ax = aw->rect.x; | ||||
|  | ||||
|   if (bw->frame) | ||||
|     bx = bw->frame->rect.x; | ||||
|   else | ||||
|     bx = bw->rect.x; | ||||
|   meta_window_get_frame_rect (aw, &a_frame); | ||||
|   meta_window_get_frame_rect (bw, &b_frame); | ||||
|   ax = a_frame.x; | ||||
|   bx = b_frame.x; | ||||
|  | ||||
|   if (ax < bx) | ||||
|     return -1; | ||||
| @@ -455,20 +433,14 @@ topmost_cmp (gconstpointer a, gconstpointer b) | ||||
| { | ||||
|   MetaWindow *aw = (gpointer) a; | ||||
|   MetaWindow *bw = (gpointer) b; | ||||
|   MetaRectangle a_frame; | ||||
|   MetaRectangle b_frame; | ||||
|   int ay, by; | ||||
|  | ||||
|   /* we're interested in the frame position for cascading, | ||||
|    * not meta_window_get_position() | ||||
|    */ | ||||
|   if (aw->frame) | ||||
|     ay = aw->frame->rect.y; | ||||
|   else | ||||
|     ay = aw->rect.y; | ||||
|  | ||||
|   if (bw->frame) | ||||
|     by = bw->frame->rect.y; | ||||
|   else | ||||
|     by = bw->rect.y; | ||||
|   meta_window_get_frame_rect (aw, &a_frame); | ||||
|   meta_window_get_frame_rect (bw, &b_frame); | ||||
|   ay = a_frame.y; | ||||
|   by = b_frame.y; | ||||
|  | ||||
|   if (ay < by) | ||||
|     return -1; | ||||
| @@ -506,7 +478,6 @@ center_tile_rect_in_area (MetaRectangle *rect, | ||||
|  */ | ||||
| static gboolean | ||||
| find_first_fit (MetaWindow *window, | ||||
|                 MetaFrameBorders *borders, | ||||
|                 /* visible windows on relevant workspaces */ | ||||
|                 GList      *windows, | ||||
| 		int         monitor, | ||||
| @@ -540,15 +511,8 @@ find_first_fit (MetaWindow *window, | ||||
|   right_sorted = g_list_copy (windows); | ||||
|   right_sorted = g_list_sort (right_sorted, topmost_cmp); | ||||
|   right_sorted = g_list_sort (right_sorted, leftmost_cmp); | ||||
|    | ||||
|   rect.width = window->rect.width; | ||||
|   rect.height = window->rect.height; | ||||
|    | ||||
|   if (borders) | ||||
|     { | ||||
|       rect.width += borders->visible.left + borders->visible.right; | ||||
|       rect.height += borders->visible.top + borders->visible.bottom; | ||||
|     } | ||||
|  | ||||
|   meta_window_get_frame_rect (window, &rect); | ||||
|  | ||||
| #ifdef WITH_VERBOSE_MODE | ||||
|     { | ||||
| @@ -570,11 +534,6 @@ find_first_fit (MetaWindow *window, | ||||
|       { | ||||
|         *new_x = rect.x; | ||||
|         *new_y = rect.y; | ||||
|         if (borders) | ||||
|           { | ||||
|             *new_x += borders->visible.left; | ||||
|             *new_y += borders->visible.top; | ||||
|           } | ||||
|      | ||||
|         retval = TRUE; | ||||
|         | ||||
| @@ -586,23 +545,18 @@ find_first_fit (MetaWindow *window, | ||||
|     while (tmp != NULL) | ||||
|       { | ||||
|         MetaWindow *w = tmp->data; | ||||
|         MetaRectangle outer_rect; | ||||
|         MetaRectangle frame_rect; | ||||
|  | ||||
|         meta_window_get_outer_rect (w, &outer_rect); | ||||
|         meta_window_get_frame_rect (w, &frame_rect); | ||||
|        | ||||
|         rect.x = outer_rect.x; | ||||
|         rect.y = outer_rect.y + outer_rect.height; | ||||
|         rect.x = frame_rect.x; | ||||
|         rect.y = frame_rect.y + frame_rect.height; | ||||
|        | ||||
|         if (meta_rectangle_contains_rect (&work_area, &rect) && | ||||
|             !rectangle_overlaps_some_window (&rect, below_sorted)) | ||||
|           { | ||||
|             *new_x = rect.x; | ||||
|             *new_y = rect.y; | ||||
|             if (borders) | ||||
|               { | ||||
|                 *new_x += borders->visible.left; | ||||
|                 *new_y += borders->visible.top; | ||||
|               } | ||||
|            | ||||
|             retval = TRUE; | ||||
|            | ||||
| @@ -617,23 +571,18 @@ find_first_fit (MetaWindow *window, | ||||
|     while (tmp != NULL) | ||||
|       { | ||||
|         MetaWindow *w = tmp->data; | ||||
|         MetaRectangle outer_rect; | ||||
|         MetaRectangle frame_rect; | ||||
|     | ||||
|         meta_window_get_outer_rect (w, &outer_rect); | ||||
|         meta_window_get_frame_rect (w, &frame_rect); | ||||
|       | ||||
|         rect.x = outer_rect.x + outer_rect.width; | ||||
|         rect.y = outer_rect.y; | ||||
|         rect.x = frame_rect.x + frame_rect.width; | ||||
|         rect.y = frame_rect.y; | ||||
|     | ||||
|         if (meta_rectangle_contains_rect (&work_area, &rect) && | ||||
|             !rectangle_overlaps_some_window (&rect, right_sorted)) | ||||
|           { | ||||
|             *new_x = rect.x; | ||||
|             *new_y = rect.y; | ||||
|             if (borders) | ||||
|               { | ||||
|                 *new_x += borders->visible.left; | ||||
|                 *new_y += borders->visible.top; | ||||
|               } | ||||
|          | ||||
|             retval = TRUE; | ||||
|         | ||||
| @@ -652,7 +601,6 @@ find_first_fit (MetaWindow *window, | ||||
|  | ||||
| void | ||||
| meta_window_place (MetaWindow        *window, | ||||
|                    MetaFrameBorders  *borders, | ||||
|                    int                x, | ||||
|                    int                y, | ||||
|                    int               *new_x, | ||||
| @@ -661,13 +609,6 @@ meta_window_place (MetaWindow        *window, | ||||
|   GList *windows; | ||||
|   const MetaMonitorInfo *xi; | ||||
|  | ||||
|   /* frame member variables should NEVER be used in here, only | ||||
|    * MetaFrameBorders. But remember borders == NULL | ||||
|    * for undecorated windows. Also, this function should | ||||
|    * NEVER have side effects other than computing the | ||||
|    * placement coordinates. | ||||
|    */ | ||||
|  | ||||
|   meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc); | ||||
|  | ||||
|   windows = NULL; | ||||
| @@ -756,7 +697,7 @@ meta_window_place (MetaWindow        *window, | ||||
|         { | ||||
|           meta_topic (META_DEBUG_PLACEMENT, | ||||
|                       "Not placing window with PPosition or USPosition set\n"); | ||||
|           avoid_being_obscured_as_second_modal_dialog (window, borders, &x, &y); | ||||
|           avoid_being_obscured_as_second_modal_dialog (window, &x, &y); | ||||
|           goto done_no_constraints; | ||||
|         } | ||||
|     } | ||||
| @@ -775,29 +716,27 @@ meta_window_place (MetaWindow        *window, | ||||
|  | ||||
|       if (parent) | ||||
|         { | ||||
|           int w; | ||||
|           MetaRectangle frame_rect, parent_frame_rect; | ||||
|  | ||||
|           meta_window_get_position (parent, &x, &y); | ||||
|           w = parent->rect.width; | ||||
|           meta_window_get_frame_rect (window, &frame_rect); | ||||
|           meta_window_get_frame_rect (parent, &parent_frame_rect); | ||||
|  | ||||
|           y = parent_frame_rect.y; | ||||
|  | ||||
|           /* center of parent */ | ||||
|           x = x + w / 2; | ||||
|           x = parent_frame_rect.x + parent_frame_rect.width / 2; | ||||
|           /* center of child over center of parent */ | ||||
|           x -= window->rect.width / 2; | ||||
|           x -= frame_rect.width / 2; | ||||
|  | ||||
|           /* "visually" center window over parent, leaving twice as | ||||
|            * much space below as on top. | ||||
|            */ | ||||
|           y += (parent->rect.height - window->rect.height)/3; | ||||
|  | ||||
|           /* put top of child's frame, not top of child's client */ | ||||
|           if (borders) | ||||
|             y += borders->visible.top; | ||||
|           y += (parent_frame_rect.height - frame_rect.height)/3; | ||||
|  | ||||
|           meta_topic (META_DEBUG_PLACEMENT, "Centered window %s over transient parent\n", | ||||
|                       window->desc); | ||||
|            | ||||
|           avoid_being_obscured_as_second_modal_dialog (window, borders, &x, &y); | ||||
|           avoid_being_obscured_as_second_modal_dialog (window, &x, &y); | ||||
|  | ||||
|           goto done; | ||||
|         } | ||||
| @@ -813,6 +752,9 @@ meta_window_place (MetaWindow        *window, | ||||
|     { | ||||
|       /* Center on current monitor */ | ||||
|       int w, h; | ||||
|       MetaRectangle frame_rect; | ||||
|  | ||||
|       meta_window_get_frame_rect (window, &frame_rect); | ||||
|  | ||||
|       /* Warning, this function is a round trip! */ | ||||
|       xi = meta_screen_get_current_monitor_info (window->screen); | ||||
| @@ -820,8 +762,8 @@ meta_window_place (MetaWindow        *window, | ||||
|       w = xi->rect.width; | ||||
|       h = xi->rect.height; | ||||
|  | ||||
|       x = (w - window->rect.width) / 2; | ||||
|       y = (h - window->rect.height) / 2; | ||||
|       x = (w - frame_rect.width) / 2; | ||||
|       y = (h - frame_rect.height) / 2; | ||||
|  | ||||
|       x += xi->rect.x; | ||||
|       y += xi->rect.y; | ||||
| @@ -865,7 +807,7 @@ meta_window_place (MetaWindow        *window, | ||||
|   x = xi->rect.x; | ||||
|   y = xi->rect.y; | ||||
|  | ||||
|   if (find_first_fit (window, borders, windows, | ||||
|   if (find_first_fit (window, windows, | ||||
|                       xi->number, | ||||
|                       x, y, &x, &y)) | ||||
|     goto done_check_denied_focus; | ||||
| @@ -878,17 +820,17 @@ meta_window_place (MetaWindow        *window, | ||||
|       !window->fullscreen) | ||||
|     { | ||||
|       MetaRectangle workarea; | ||||
|       MetaRectangle outer; | ||||
|       MetaRectangle frame_rect; | ||||
|  | ||||
|       meta_window_get_work_area_for_monitor (window, | ||||
|                                              xi->number, | ||||
|                                              &workarea);       | ||||
|       meta_window_get_outer_rect (window, &outer); | ||||
|       meta_window_get_frame_rect (window, &frame_rect); | ||||
|        | ||||
|       /* If the window is bigger than the screen, then automaximize.  Do NOT | ||||
|        * auto-maximize the directions independently.  See #419810. | ||||
|        */ | ||||
|       if (outer.width >= workarea.width && outer.height >= workarea.height) | ||||
|       if (frame_rect.width >= workarea.width && frame_rect.height >= workarea.height) | ||||
|         { | ||||
|           window->maximize_horizontally_after_placement = TRUE; | ||||
|           window->maximize_vertically_after_placement = TRUE; | ||||
| @@ -899,7 +841,7 @@ meta_window_place (MetaWindow        *window, | ||||
|    * fully overlapping window (e.g. starting multiple terminals) | ||||
|    * */ | ||||
|   if (x == xi->rect.x && y == xi->rect.y)   | ||||
|     find_next_cascade (window, borders, windows, x, y, &x, &y); | ||||
|     find_next_cascade (window, windows, x, y, &x, &y); | ||||
|  | ||||
|  done_check_denied_focus: | ||||
|   /* If the window is being denied focus and isn't a transient of the | ||||
| @@ -909,17 +851,14 @@ meta_window_place (MetaWindow        *window, | ||||
|    */ | ||||
|   if (window->denied_focus_and_not_transient) | ||||
|     { | ||||
|       gboolean       found_fit; | ||||
|       MetaWindow    *focus_window; | ||||
|       MetaRectangle  overlap; | ||||
|       gboolean       found_fit; | ||||
|  | ||||
|       focus_window = window->display->focus_window; | ||||
|       g_assert (focus_window != NULL); | ||||
|  | ||||
|       /* No need to do anything if the window doesn't overlap at all */ | ||||
|       found_fit = !meta_rectangle_intersect (&window->rect, | ||||
|                                              &focus_window->rect, | ||||
|                                              &overlap); | ||||
|       found_fit = !window_overlaps_focus_window (window); | ||||
|  | ||||
|       /* Try to do a first fit again, this time only taking into account the | ||||
|        * focus window. | ||||
| @@ -933,7 +872,7 @@ meta_window_place (MetaWindow        *window, | ||||
|           x = xi->rect.x; | ||||
|           y = xi->rect.y; | ||||
|  | ||||
|           found_fit = find_first_fit (window, borders, focus_window_list, | ||||
|           found_fit = find_first_fit (window, focus_window_list, | ||||
|                                       xi->number, | ||||
|                                       x, y, &x, &y); | ||||
|           g_list_free (focus_window_list); | ||||
| @@ -943,7 +882,7 @@ meta_window_place (MetaWindow        *window, | ||||
|        * as possible. | ||||
|        */ | ||||
|       if (!found_fit) | ||||
|         find_most_freespace (window, borders, focus_window, x, y, &x, &y); | ||||
|         find_most_freespace (window, focus_window, x, y, &x, &y); | ||||
|     } | ||||
|    | ||||
|  done: | ||||
|   | ||||
| @@ -28,7 +28,6 @@ | ||||
| #include "frame.h" | ||||
|  | ||||
| void meta_window_place (MetaWindow *window, | ||||
|                         MetaFrameBorders *borders, | ||||
|                         int         x, | ||||
|                         int         y, | ||||
|                         int        *new_x, | ||||
|   | ||||
| @@ -859,9 +859,9 @@ meta_screen_free (MetaScreen *screen, | ||||
|                   screen->wm_sn_selection_window); | ||||
|    | ||||
|   if (screen->work_area_later != 0) | ||||
|     g_source_remove (screen->work_area_later); | ||||
|     meta_later_remove (screen->work_area_later); | ||||
|   if (screen->check_fullscreen_later != 0) | ||||
|     g_source_remove (screen->check_fullscreen_later); | ||||
|     meta_later_remove (screen->check_fullscreen_later); | ||||
|  | ||||
|   if (screen->monitor_infos) | ||||
|     g_free (screen->monitor_infos); | ||||
| @@ -1528,7 +1528,7 @@ meta_screen_tab_popup_create (MetaScreen      *screen, | ||||
|       if (show_type == META_TAB_SHOW_INSTANTLY || | ||||
|           !entries[i].hidden                   || | ||||
|           !meta_window_get_icon_geometry (window, &r)) | ||||
|         meta_window_get_outer_rect (window, &r); | ||||
|         meta_window_get_frame_rect (window, &r); | ||||
|  | ||||
|       entries[i].rect = r; | ||||
|  | ||||
| @@ -1911,7 +1911,7 @@ meta_screen_get_monitor_for_window (MetaScreen *screen, | ||||
| { | ||||
|   MetaRectangle window_rect; | ||||
|    | ||||
|   meta_window_get_outer_rect (window, &window_rect); | ||||
|   meta_window_get_frame_rect (window, &window_rect); | ||||
|  | ||||
|   return meta_screen_get_monitor_for_rect (screen, &window_rect); | ||||
| } | ||||
|   | ||||
| @@ -1465,7 +1465,7 @@ window_contains_point (MetaWindow *window, | ||||
| { | ||||
|   MetaRectangle rect; | ||||
|  | ||||
|   meta_window_get_outer_rect (window, &rect); | ||||
|   meta_window_get_frame_rect (window, &rect); | ||||
|  | ||||
|   return POINT_IN_RECT (root_x, root_y, rect); | ||||
| } | ||||
|   | ||||
| @@ -36,6 +36,7 @@ | ||||
|  | ||||
| #include <config.h> | ||||
| #include <meta/compositor.h> | ||||
| #include <meta/meta-window-actor.h> | ||||
| #include <meta/window.h> | ||||
| #include "screen-private.h" | ||||
| #include <meta/util.h> | ||||
| @@ -352,6 +353,9 @@ struct _MetaWindow | ||||
|   /* if non-NULL, the opaque region _NET_WM_OPAQUE_REGION */ | ||||
|   cairo_region_t *opaque_region; | ||||
|  | ||||
|   /* the input shape region for picking */ | ||||
|   cairo_region_t *input_region; | ||||
|  | ||||
|   /* if TRUE, the we have the new form of sync request counter which | ||||
|    * also handles application frames */ | ||||
|   guint extended_sync_request_counter : 1; | ||||
| @@ -435,7 +439,10 @@ struct _MetaWindow | ||||
|   /* maintained by group.c */ | ||||
|   MetaGroup *group; | ||||
|  | ||||
|   GObject *compositor_private; | ||||
|   GSList *actors; | ||||
|  | ||||
|   /* The core actor is the one in the window group. */ | ||||
|   MetaWindowActor *core_actor; | ||||
|  | ||||
|   /* Focused window that is (directly or indirectly) attached to this one */ | ||||
|   MetaWindow *attached_focus_window; | ||||
| @@ -512,6 +519,7 @@ void        meta_window_update_fullscreen_monitors (MetaWindow    *window, | ||||
|                                                     unsigned long  left, | ||||
|                                                     unsigned long  right); | ||||
|  | ||||
|  | ||||
| /* args to move are window pos, not frame pos */ | ||||
| void        meta_window_move               (MetaWindow  *window, | ||||
|                                             gboolean     user_op, | ||||
| @@ -655,6 +663,8 @@ void meta_window_recalc_features    (MetaWindow *window); | ||||
|  | ||||
| void meta_window_recalc_window_type (MetaWindow *window); | ||||
|  | ||||
| void meta_window_frame_size_changed (MetaWindow *window); | ||||
|  | ||||
| void meta_window_stack_just_below (MetaWindow *window, | ||||
|                                    MetaWindow *below_this_one); | ||||
|  | ||||
| @@ -682,8 +692,14 @@ void meta_window_set_opaque_region        (MetaWindow     *window, | ||||
|                                            cairo_region_t *region); | ||||
| void meta_window_update_opaque_region_x11 (MetaWindow *window); | ||||
|  | ||||
| void meta_window_set_input_region         (MetaWindow     *window, | ||||
|                                            cairo_region_t *region); | ||||
| void meta_window_update_input_region_x11  (MetaWindow *window); | ||||
|  | ||||
| void meta_window_set_shape_region         (MetaWindow     *window, | ||||
|                                            cairo_region_t *region); | ||||
| void meta_window_update_shape_region_x11  (MetaWindow *window); | ||||
|  | ||||
| Window meta_window_get_toplevel_xwindow (MetaWindow *window); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -316,6 +316,9 @@ reload_gtk_frame_extents (MetaWindow    *window, | ||||
|     { | ||||
|       window->has_custom_frame_extents = FALSE; | ||||
|     } | ||||
|  | ||||
|   if (!initial) | ||||
|     meta_window_queue(window, META_QUEUE_MOVE_RESIZE); | ||||
| } | ||||
|  | ||||
| static void | ||||
|   | ||||
| @@ -194,6 +194,8 @@ enum | ||||
|   FOCUS, | ||||
|   RAISED, | ||||
|   UNMANAGED, | ||||
|   SIZE_CHANGED, | ||||
|   POSITION_CHANGED, | ||||
|  | ||||
|   LAST_SIGNAL | ||||
| }; | ||||
| @@ -587,6 +589,22 @@ meta_window_class_init (MetaWindowClass *klass) | ||||
|                   G_STRUCT_OFFSET (MetaWindowClass, unmanaged), | ||||
|                   NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 0); | ||||
|  | ||||
|   window_signals[POSITION_CHANGED] = | ||||
|     g_signal_new ("position-changed", | ||||
|                   G_TYPE_FROM_CLASS (object_class), | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   0, | ||||
|                   NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 0); | ||||
|  | ||||
|   window_signals[SIZE_CHANGED] = | ||||
|     g_signal_new ("size-changed", | ||||
|                   G_TYPE_FROM_CLASS (object_class), | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   0, | ||||
|                   NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 0); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -1175,7 +1193,8 @@ meta_window_new_with_attrs (MetaDisplay       *display, | ||||
|   window->initial_workspace = 0; /* not used */ | ||||
|   window->initial_timestamp = 0; /* not used */ | ||||
|  | ||||
|   window->compositor_private = NULL; | ||||
|   window->core_actor = NULL; | ||||
|   window->actors = NULL; | ||||
|  | ||||
|   window->monitor = meta_screen_get_monitor_for_window (window->screen, window); | ||||
|  | ||||
| @@ -1194,6 +1213,7 @@ meta_window_new_with_attrs (MetaDisplay       *display, | ||||
|   meta_display_register_x_window (display, &window->xwindow, window); | ||||
|  | ||||
|   meta_window_update_shape_region_x11 (window); | ||||
|   meta_window_update_input_region_x11 (window); | ||||
|  | ||||
|   /* Assign this #MetaWindow a sequence number which can be used | ||||
|    * for sorting. | ||||
| @@ -1869,6 +1889,8 @@ meta_window_unmanage (MetaWindow  *window, | ||||
|   meta_window_ungrab_keys (window); | ||||
|   meta_display_ungrab_window_buttons (window->display, window->xwindow); | ||||
|   meta_display_ungrab_focus_window_button (window->display, window); | ||||
|   if (window->display->autoraise_window == window) | ||||
|     meta_display_remove_autoraise_callback (window->display); | ||||
|  | ||||
|   meta_display_unregister_x_window (window->display, window->xwindow); | ||||
|  | ||||
| @@ -2791,8 +2813,8 @@ static gboolean | ||||
| windows_overlap (const MetaWindow *w1, const MetaWindow *w2) | ||||
| { | ||||
|   MetaRectangle w1rect, w2rect; | ||||
|   meta_window_get_outer_rect (w1, &w1rect); | ||||
|   meta_window_get_outer_rect (w2, &w2rect); | ||||
|   meta_window_get_frame_rect (w1, &w1rect); | ||||
|   meta_window_get_frame_rect (w2, &w2rect); | ||||
|   return meta_rectangle_overlap (&w1rect, &w2rect); | ||||
| } | ||||
|  | ||||
| @@ -3593,11 +3615,11 @@ meta_window_maximize (MetaWindow        *window, | ||||
|           MetaRectangle old_rect; | ||||
| 	  MetaRectangle new_rect; | ||||
|  | ||||
| 	  meta_window_get_outer_rect (window, &old_rect); | ||||
| 	  meta_window_get_frame_rect (window, &old_rect); | ||||
|  | ||||
|           meta_window_move_resize_now (window); | ||||
|  | ||||
| 	  meta_window_get_outer_rect (window, &new_rect); | ||||
| 	  meta_window_get_frame_rect (window, &new_rect); | ||||
|           meta_compositor_maximize_window (window->display->compositor, | ||||
|                                            window, | ||||
|                                            &old_rect, | ||||
| @@ -3656,7 +3678,7 @@ meta_window_get_all_monitors (MetaWindow *window, gsize *length) | ||||
|   int i; | ||||
|  | ||||
|   monitors = g_array_new (FALSE, FALSE, sizeof (int)); | ||||
|   meta_window_get_outer_rect (window, &window_rect); | ||||
|   meta_window_get_frame_rect (window, &window_rect); | ||||
|  | ||||
|   for (i = 0; i < window->screen->n_monitor_infos; i++) | ||||
|     { | ||||
| @@ -3689,7 +3711,7 @@ meta_window_is_screen_sized (MetaWindow *window) | ||||
|   int screen_width, screen_height; | ||||
|  | ||||
|   meta_screen_get_size (window->screen, &screen_width, &screen_height); | ||||
|   meta_window_get_outer_rect (window, &window_rect); | ||||
|   meta_window_get_frame_rect (window, &window_rect); | ||||
|  | ||||
|   if (window_rect.x == 0 && window_rect.y == 0 && | ||||
|       window_rect.width == screen_width && window_rect.height == screen_height) | ||||
| @@ -3718,7 +3740,7 @@ meta_window_is_monitor_sized (MetaWindow *window) | ||||
|     { | ||||
|       MetaRectangle window_rect, monitor_rect; | ||||
|  | ||||
|       meta_window_get_outer_rect (window, &window_rect); | ||||
|       meta_window_get_frame_rect (window, &window_rect); | ||||
|       meta_screen_get_monitor_geometry (window->screen, window->monitor->number, &monitor_rect); | ||||
|  | ||||
|       if (meta_rectangle_equal (&window_rect, &monitor_rect)) | ||||
| @@ -3786,11 +3808,11 @@ meta_window_tile (MetaWindow *window) | ||||
|       MetaRectangle old_rect; | ||||
|       MetaRectangle new_rect; | ||||
|  | ||||
|       meta_window_get_outer_rect (window, &old_rect); | ||||
|       meta_window_get_frame_rect (window, &old_rect); | ||||
|  | ||||
|       meta_window_move_resize_now (window); | ||||
|  | ||||
|       meta_window_get_outer_rect (window, &new_rect); | ||||
|       meta_window_get_frame_rect (window, &new_rect); | ||||
|       meta_compositor_maximize_window (window->display->compositor, | ||||
|                                        window, | ||||
|                                        &old_rect, | ||||
| @@ -3819,7 +3841,7 @@ meta_window_can_tile_side_by_side (MetaWindow *window) | ||||
| { | ||||
|   int monitor; | ||||
|   MetaRectangle tile_area; | ||||
|   MetaFrameBorders borders; | ||||
|   MetaRectangle client_rect; | ||||
|  | ||||
|   if (!meta_window_can_tile_maximized (window)) | ||||
|     return FALSE; | ||||
| @@ -3833,13 +3855,10 @@ meta_window_can_tile_side_by_side (MetaWindow *window) | ||||
|  | ||||
|   tile_area.width /= 2; | ||||
|  | ||||
|   meta_frame_calc_borders (window->frame, &borders); | ||||
|   meta_window_frame_rect_to_client_rect (window, &tile_area, &client_rect); | ||||
|  | ||||
|   tile_area.width  -= (borders.visible.left + borders.visible.right); | ||||
|   tile_area.height -= (borders.visible.top + borders.visible.bottom); | ||||
|  | ||||
|   return tile_area.width >= window->size_hints.min_width && | ||||
|          tile_area.height >= window->size_hints.min_height; | ||||
|   return client_rect.width >= window->size_hints.min_width && | ||||
|          client_rect.height >= window->size_hints.min_height; | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -3900,8 +3919,10 @@ meta_window_unmaximize_internal (MetaWindow        *window, | ||||
|     { | ||||
|       MetaRectangle target_rect; | ||||
|       MetaRectangle work_area; | ||||
|       MetaRectangle old_rect; | ||||
|  | ||||
|       meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area); | ||||
|       meta_window_get_frame_rect (window, &old_rect); | ||||
|  | ||||
|       meta_topic (META_DEBUG_WINDOW_OPS, | ||||
|                   "Unmaximizing %s%s\n", | ||||
| @@ -3915,6 +3936,12 @@ meta_window_unmaximize_internal (MetaWindow        *window, | ||||
|       window->maximized_vertically = | ||||
|         window->maximized_vertically   && !unmaximize_vertically; | ||||
|  | ||||
|       /* recalc_window_features() will eventually clear the cached frame | ||||
|        * extents, but we need the correct frame extents in the code below, | ||||
|        * so invalidate the old frame extents manually up front. | ||||
|        */ | ||||
|       meta_window_frame_size_changed (window); | ||||
|  | ||||
|       /* Unmaximize to the saved_rect position in the direction(s) | ||||
|        * being unmaximized. | ||||
|        */ | ||||
| @@ -3959,9 +3986,7 @@ meta_window_unmaximize_internal (MetaWindow        *window, | ||||
|  | ||||
|       if (window->display->compositor) | ||||
|         { | ||||
|           MetaRectangle old_rect, new_rect; | ||||
|  | ||||
| 	  meta_window_get_outer_rect (window, &old_rect); | ||||
|           MetaRectangle new_rect; | ||||
|  | ||||
|           meta_window_move_resize_internal (window, | ||||
|                                             META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION, | ||||
| @@ -3971,7 +3996,7 @@ meta_window_unmaximize_internal (MetaWindow        *window, | ||||
|                                             target_rect.width, | ||||
|                                             target_rect.height); | ||||
|  | ||||
| 	  meta_window_get_outer_rect (window, &new_rect); | ||||
| 	  meta_window_get_frame_rect (window, &new_rect); | ||||
|           meta_compositor_unmaximize_window (window->display->compositor, | ||||
| 					     window, | ||||
|                                              &old_rect, | ||||
| @@ -4076,6 +4101,7 @@ meta_window_set_above (MetaWindow *window, | ||||
|   window->wm_state_above = new_value; | ||||
|   meta_window_update_layer (window); | ||||
|   set_net_wm_state (window); | ||||
|   meta_window_frame_size_changed (window); | ||||
|   g_object_notify (G_OBJECT (window), "above"); | ||||
| } | ||||
|  | ||||
| @@ -4215,6 +4241,7 @@ meta_window_shade (MetaWindow  *window, | ||||
|       window->shaded = TRUE; | ||||
|  | ||||
|       meta_window_queue(window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING); | ||||
|       meta_window_frame_size_changed (window); | ||||
|  | ||||
|       /* After queuing the calc showing, since _focus flushes it, | ||||
|        * and we need to focus the frame | ||||
| @@ -4240,6 +4267,7 @@ meta_window_unshade (MetaWindow  *window, | ||||
|     { | ||||
|       window->shaded = FALSE; | ||||
|       meta_window_queue(window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING); | ||||
|       meta_window_frame_size_changed (window); | ||||
|  | ||||
|       /* focus the window */ | ||||
|       meta_topic (META_DEBUG_FOCUS, | ||||
| @@ -4967,7 +4995,6 @@ meta_window_move_resize_internal (MetaWindow          *window, | ||||
|   did_placement = !window->placed && window->calc_placement; | ||||
|  | ||||
|   meta_window_constrain (window, | ||||
|                          window->frame ? &borders : NULL, | ||||
|                          flags, | ||||
|                          gravity, | ||||
|                          &old_rect, | ||||
| @@ -5275,6 +5302,12 @@ meta_window_move_resize_internal (MetaWindow          *window, | ||||
|   else if (is_user_action) | ||||
|     save_user_window_placement (window); | ||||
|  | ||||
|   if (need_move_frame) | ||||
|     g_signal_emit (window, window_signals[POSITION_CHANGED], 0); | ||||
|  | ||||
|   if (need_resize_client) | ||||
|     g_signal_emit (window, window_signals[SIZE_CHANGED], 0); | ||||
|  | ||||
|   if (need_move_frame || need_resize_frame || | ||||
|       need_move_client || need_resize_client || | ||||
|       did_placement) | ||||
| @@ -5396,23 +5429,10 @@ meta_window_move_frame (MetaWindow  *window, | ||||
|                   int          root_x_nw, | ||||
|                   int          root_y_nw) | ||||
| { | ||||
|   int x = root_x_nw; | ||||
|   int y = root_y_nw; | ||||
|   MetaRectangle rect = { root_x_nw, root_y_nw, 0, 0 }; | ||||
|  | ||||
|   if (window->frame) | ||||
|     { | ||||
|       MetaFrameBorders borders; | ||||
|       meta_frame_calc_borders (window->frame, &borders); | ||||
|  | ||||
|       /* root_x_nw and root_y_nw correspond to where the top of | ||||
|        * the visible frame should be. Offset by the distance between | ||||
|        * the origin of the window and the origin of the enclosing | ||||
|        * window decorations. | ||||
|        */ | ||||
|       x += window->frame->child_x - borders.invisible.left; | ||||
|       y += window->frame->child_y - borders.invisible.top; | ||||
|     } | ||||
|   meta_window_move (window, user_op, x, y); | ||||
|   meta_window_frame_rect_to_client_rect (window, &rect, &rect); | ||||
|   meta_window_move (window, user_op, rect.x, rect.y); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -5460,18 +5480,10 @@ meta_window_move_resize_frame (MetaWindow  *window, | ||||
|                                int          w, | ||||
|                                int          h) | ||||
| { | ||||
|   MetaFrameBorders borders; | ||||
|   MetaRectangle rect = { root_x_nw, root_y_nw, w, h }; | ||||
|   meta_window_frame_rect_to_client_rect (window, &rect, &rect); | ||||
|  | ||||
|   meta_frame_calc_borders (window->frame, &borders); | ||||
|   /* offset by the distance between the origin of the window | ||||
|    * and the origin of the enclosing window decorations ( + border) | ||||
|    */ | ||||
|   root_x_nw += borders.visible.left; | ||||
|   root_y_nw += borders.visible.top; | ||||
|   w -= borders.visible.left + borders.visible.right; | ||||
|   h -= borders.visible.top + borders.visible.bottom; | ||||
|  | ||||
|   meta_window_move_resize (window, user_op, root_x_nw, root_y_nw, w, h); | ||||
|   meta_window_move_resize (window, user_op, rect.x, rect.y, rect.width, rect.height); | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -5784,16 +5796,110 @@ meta_window_get_input_rect (const MetaWindow *window, | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_window_get_outer_rect: | ||||
|  * meta_window_client_rect_to_frame_rect: | ||||
|  * @window: a #MetaWindow | ||||
|  * @client_rect: client rectangle in root coordinates | ||||
|  * @frame_rect: (out): location to store the computed corresponding frame bounds. | ||||
|  * | ||||
|  * Converts a desired bounds of the client window - what is passed to meta_window_move_resize() - | ||||
|  * into the corresponding bounds of the window frame (excluding invisible borders | ||||
|  * and client side shadows.) | ||||
|  */ | ||||
| void | ||||
| meta_window_client_rect_to_frame_rect (MetaWindow    *window, | ||||
|                                        MetaRectangle *client_rect, | ||||
|                                        MetaRectangle *frame_rect) | ||||
| { | ||||
|   if (!frame_rect) | ||||
|     return; | ||||
|  | ||||
|   *frame_rect = *client_rect; | ||||
|  | ||||
|   /* The support for G_MAXINT here to mean infinity is a convenience for | ||||
|    * constraints.c:get_size_limits() and not something that we provide | ||||
|    * in other locations or document. | ||||
|    */ | ||||
|   if (window->frame) | ||||
|     { | ||||
|       MetaFrameBorders borders; | ||||
|       meta_frame_calc_borders (window->frame, &borders); | ||||
|  | ||||
|       frame_rect->x -= borders.visible.left; | ||||
|       frame_rect->y -= borders.visible.top; | ||||
|       if (frame_rect->width != G_MAXINT) | ||||
|         frame_rect->width += borders.visible.left + borders.visible.right; | ||||
|       if (frame_rect->height != G_MAXINT) | ||||
|         frame_rect->height += borders.visible.top  + borders.visible.bottom; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if (window->has_custom_frame_extents) | ||||
|         { | ||||
|           const GtkBorder *extents = &window->custom_frame_extents; | ||||
|           frame_rect->x += extents->left; | ||||
|           frame_rect->y += extents->top; | ||||
|           if (frame_rect->width != G_MAXINT) | ||||
|             frame_rect->width -= extents->left + extents->right; | ||||
|           if (frame_rect->height != G_MAXINT) | ||||
|             frame_rect->height -= extents->top + extents->bottom; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_window_frame_rect_to_client_rect: | ||||
|  * @window: a #MetaWindow | ||||
|  * @frame_rect: desired frame bounds for the window | ||||
|  * @client_rect: (out): location to store the computed corresponding client rectangle. | ||||
|  * | ||||
|  * Converts a desired frame bounds for a window into the bounds of the client | ||||
|  * window - what is passed to meta_window_move_resize(). | ||||
|  */ | ||||
| void | ||||
| meta_window_frame_rect_to_client_rect (MetaWindow    *window, | ||||
|                                        MetaRectangle *frame_rect, | ||||
|                                        MetaRectangle *client_rect) | ||||
| { | ||||
|   if (!client_rect) | ||||
|     return; | ||||
|  | ||||
|   *client_rect = *frame_rect; | ||||
|  | ||||
|   if (window->frame) | ||||
|     { | ||||
|       MetaFrameBorders borders; | ||||
|       meta_frame_calc_borders (window->frame, &borders); | ||||
|  | ||||
|       client_rect->x += borders.visible.left; | ||||
|       client_rect->y += borders.visible.top; | ||||
|       client_rect->width  -= borders.visible.left + borders.visible.right; | ||||
|       client_rect->height -= borders.visible.top  + borders.visible.bottom; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if (window->has_custom_frame_extents) | ||||
|         { | ||||
|           const GtkBorder *extents = &window->custom_frame_extents; | ||||
|           client_rect->x -= extents->left; | ||||
|           client_rect->y -= extents->top; | ||||
|           client_rect->width += extents->left + extents->right; | ||||
|           client_rect->height += extents->top + extents->bottom; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_window_get_frame_rect: | ||||
|  * @window: a #MetaWindow | ||||
|  * @rect: (out): pointer to an allocated #MetaRectangle | ||||
|  * | ||||
|  * Gets the rectangle that bounds @window that is responsive to mouse events. | ||||
|  * This includes only what is visible; it doesn't include any extra reactive | ||||
|  * area we add to the edges of windows. | ||||
|  * Gets the rectangle that bounds @window that is what the user thinks of | ||||
|  * as the edge of the window. This doesn't include any extra reactive | ||||
|  * area that we or the client adds to the window, or any area that the | ||||
|  * client adds to draw a client-side shadow. | ||||
|  */ | ||||
| void | ||||
| meta_window_get_outer_rect (const MetaWindow *window, | ||||
| meta_window_get_frame_rect (const MetaWindow *window, | ||||
|                             MetaRectangle    *rect) | ||||
| { | ||||
|   if (window->frame) | ||||
| @@ -5822,6 +5928,25 @@ meta_window_get_outer_rect (const MetaWindow *window, | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_window_get_outer_rect: | ||||
|  * @window: a #MetaWindow | ||||
|  * @rect: (out): pointer to an allocated #MetaRectangle | ||||
|  * | ||||
|  * Gets the rectangle that bounds @window that is what the user thinks of | ||||
|  * as the edge of the window. This doesn't include any extra reactive | ||||
|  * area that we or the client adds to the window, or any area that the | ||||
|  * client adds to draw a client-side shadow. | ||||
|  * | ||||
|  * Deprecated: 3.12: Use meta_window_get_frame_rect() instead. | ||||
|  */ | ||||
| void | ||||
| meta_window_get_outer_rect (const MetaWindow *window, | ||||
|                             MetaRectangle    *rect) | ||||
| { | ||||
|   meta_window_get_frame_rect (window, rect); | ||||
| } | ||||
|  | ||||
| const char* | ||||
| meta_window_get_startup_id (MetaWindow *window) | ||||
| { | ||||
| @@ -6043,6 +6168,7 @@ window_stick_impl (MetaWindow  *window) | ||||
|    * toggled back off. | ||||
|    */ | ||||
|   window->on_all_workspaces_requested = TRUE; | ||||
|   meta_window_frame_size_changed (window); | ||||
|   meta_window_update_on_all_workspaces (window); | ||||
|  | ||||
|   meta_window_queue(window, META_QUEUE_CALC_SHOWING); | ||||
| @@ -6057,6 +6183,7 @@ window_unstick_impl (MetaWindow  *window) | ||||
|   /* Revert to window->workspaces */ | ||||
|  | ||||
|   window->on_all_workspaces_requested = FALSE; | ||||
|   meta_window_frame_size_changed (window); | ||||
|   meta_window_update_on_all_workspaces (window); | ||||
|  | ||||
|   /* We change ourselves to the active workspace, since otherwise you'd get | ||||
| @@ -7132,6 +7259,7 @@ static void | ||||
| meta_window_appears_focused_changed (MetaWindow *window) | ||||
| { | ||||
|   set_net_wm_state (window); | ||||
|   meta_window_frame_size_changed (window); | ||||
|  | ||||
|   g_object_notify (G_OBJECT (window), "appears-focused"); | ||||
|  | ||||
| @@ -7712,6 +7840,91 @@ meta_window_set_shape_region (MetaWindow     *window, | ||||
|     meta_compositor_window_shape_changed (window->display->compositor, window); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_window_update_input_region_x11 (MetaWindow *window) | ||||
| { | ||||
|   cairo_region_t *region = NULL; | ||||
|  | ||||
| #ifdef HAVE_SHAPE | ||||
|   if (META_DISPLAY_HAS_SHAPE (window->display)) | ||||
|     { | ||||
|       /* Translate the set of XShape rectangles that we | ||||
|        * get from the X server to a cairo_region. */ | ||||
|       XRectangle *rects = NULL; | ||||
|       int n_rects, ordering; | ||||
|  | ||||
|       int x_bounding, y_bounding, x_clip, y_clip; | ||||
|       unsigned w_bounding, h_bounding, w_clip, h_clip; | ||||
|       int bounding_shaped, clip_shaped; | ||||
|  | ||||
|       meta_error_trap_push (window->display); | ||||
|       XShapeQueryExtents (window->display->xdisplay, window->xwindow, | ||||
|                           &bounding_shaped, &x_bounding, &y_bounding, | ||||
|                           &w_bounding, &h_bounding, | ||||
|                           &clip_shaped, &x_clip, &y_clip, | ||||
|                           &w_clip, &h_clip); | ||||
|  | ||||
|       rects = XShapeGetRectangles (window->display->xdisplay, | ||||
|                                    window->xwindow, | ||||
|                                    ShapeInput, | ||||
|                                    &n_rects, | ||||
|                                    &ordering); | ||||
|       meta_error_trap_pop (window->display); | ||||
|  | ||||
|       /* XXX: The x shape extension doesn't provide a way to only test if an | ||||
|        * input shape has been specified, so we have to query and throw away the | ||||
|        * rectangles. */ | ||||
|       if (rects) | ||||
|         { | ||||
|           if (n_rects > 1 || | ||||
|               (n_rects == 1 && | ||||
|                (rects[0].x != x_bounding || | ||||
|                 rects[1].y != y_bounding || | ||||
|                 rects[2].width != w_bounding || | ||||
|                 rects[3].height != h_bounding))) | ||||
|             region = region_create_from_x_rectangles (rects, n_rects); | ||||
|  | ||||
|           XFree (rects); | ||||
|         } | ||||
|     } | ||||
| #endif /* HAVE_SHAPE */ | ||||
|  | ||||
|   if (region != NULL) | ||||
|     { | ||||
|       cairo_rectangle_int_t client_area; | ||||
|  | ||||
|       client_area.x = 0; | ||||
|       client_area.y = 0; | ||||
|       client_area.width = window->rect.width; | ||||
|       client_area.height = window->rect.height; | ||||
|  | ||||
|       /* The shape we get back from the client may have coordinates | ||||
|        * outside of the frame. The X SHAPE Extension requires that | ||||
|        * the overall shape the client provides never exceeds the | ||||
|        * "bounding rectangle" of the window -- the shape that the | ||||
|        * window would have gotten if it was unshaped. In our case, | ||||
|        * this is simply the client area. | ||||
|        */ | ||||
|       cairo_region_intersect_rectangle (region, &client_area); | ||||
|     } | ||||
|  | ||||
|   meta_window_set_input_region (window, region); | ||||
|   cairo_region_destroy (region); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_window_set_input_region (MetaWindow     *window, | ||||
|                               cairo_region_t *region) | ||||
| { | ||||
|   g_clear_pointer (&window->input_region, cairo_region_destroy); | ||||
|  | ||||
|   if (region != NULL) | ||||
|     window->input_region = cairo_region_reference (region); | ||||
|  | ||||
|   if (window->display->compositor) | ||||
|     meta_compositor_window_shape_changed (window->display->compositor, window); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_window_update_shape_region_x11 (MetaWindow *window) | ||||
| { | ||||
| @@ -8219,6 +8432,13 @@ recalc_window_type (MetaWindow *window) | ||||
|     } | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_window_frame_size_changed (MetaWindow *window) | ||||
| { | ||||
|   if (window->frame) | ||||
|     meta_frame_clear_cached_borders (window->frame); | ||||
| } | ||||
|  | ||||
| static void | ||||
| set_allowed_actions_hint (MetaWindow *window) | ||||
| { | ||||
| @@ -8418,18 +8638,13 @@ recalc_window_features (MetaWindow *window) | ||||
|  | ||||
|   if (window->has_maximize_func) | ||||
|     { | ||||
|       MetaRectangle work_area; | ||||
|       MetaFrameBorders borders; | ||||
|       int min_frame_width, min_frame_height; | ||||
|       MetaRectangle work_area, client_rect; | ||||
|  | ||||
|       meta_window_get_work_area_current_monitor (window, &work_area); | ||||
|       meta_frame_calc_borders (window->frame, &borders); | ||||
|       meta_window_frame_rect_to_client_rect (window, &work_area, &client_rect); | ||||
|  | ||||
|       min_frame_width = window->size_hints.min_width + borders.visible.left + borders.visible.right; | ||||
|       min_frame_height = window->size_hints.min_height + borders.visible.top + borders.visible.bottom; | ||||
|  | ||||
|       if (min_frame_width >= work_area.width || | ||||
|           min_frame_height >= work_area.height) | ||||
|       if (window->size_hints.min_width >= client_rect.width || | ||||
|           window->size_hints.min_height >= client_rect.height) | ||||
|         window->has_maximize_func = FALSE; | ||||
|     } | ||||
|  | ||||
| @@ -8522,6 +8737,8 @@ recalc_window_features (MetaWindow *window) | ||||
|   if (window->has_resize_func != old_has_resize_func) | ||||
|     g_object_notify (G_OBJECT (window), "resizeable"); | ||||
|  | ||||
|   meta_window_frame_size_changed (window); | ||||
|  | ||||
|   /* FIXME perhaps should ensure if we don't have a shade func, | ||||
|    * we aren't shaded, etc. | ||||
|    */ | ||||
| @@ -8798,7 +9015,7 @@ meta_window_show_menu (MetaWindow *window, | ||||
| void | ||||
| meta_window_shove_titlebar_onscreen (MetaWindow *window) | ||||
| { | ||||
|   MetaRectangle  outer_rect; | ||||
|   MetaRectangle  frame_rect; | ||||
|   GList         *onscreen_region; | ||||
|   int            horiz_amount, vert_amount; | ||||
|   int            newx, newy; | ||||
| @@ -8810,15 +9027,15 @@ meta_window_shove_titlebar_onscreen (MetaWindow *window) | ||||
|     return; | ||||
|  | ||||
|   /* Get the basic info we need */ | ||||
|   meta_window_get_outer_rect (window, &outer_rect); | ||||
|   meta_window_get_frame_rect (window, &frame_rect); | ||||
|   onscreen_region = window->screen->active_workspace->screen_region; | ||||
|  | ||||
|   /* Extend the region (just in case the window is too big to fit on the | ||||
|    * screen), then shove the window on screen, then return the region to | ||||
|    * normal. | ||||
|    */ | ||||
|   horiz_amount = outer_rect.width; | ||||
|   vert_amount  = outer_rect.height; | ||||
|   horiz_amount = frame_rect.width; | ||||
|   vert_amount  = frame_rect.height; | ||||
|   meta_rectangle_expand_region (onscreen_region, | ||||
|                                 horiz_amount, | ||||
|                                 horiz_amount, | ||||
| @@ -8826,15 +9043,15 @@ meta_window_shove_titlebar_onscreen (MetaWindow *window) | ||||
|                                 vert_amount); | ||||
|   meta_rectangle_shove_into_region(onscreen_region, | ||||
|                                    FIXED_DIRECTION_X, | ||||
|                                    &outer_rect); | ||||
|                                    &frame_rect); | ||||
|   meta_rectangle_expand_region (onscreen_region, | ||||
|                                 -horiz_amount, | ||||
|                                 -horiz_amount, | ||||
|                                 0, | ||||
|                                 -vert_amount); | ||||
|  | ||||
|   newx = outer_rect.x + window->frame->child_x; | ||||
|   newy = outer_rect.y + window->frame->child_y; | ||||
|   newx = frame_rect.x + window->frame->child_x; | ||||
|   newy = frame_rect.y + window->frame->child_y; | ||||
|   meta_window_move_resize (window, | ||||
|                            FALSE, | ||||
|                            newx, | ||||
| @@ -8859,7 +9076,7 @@ meta_window_titlebar_is_onscreen (MetaWindow *window) | ||||
|     return FALSE; | ||||
|  | ||||
|   /* Get the rectangle corresponding to the titlebar */ | ||||
|   meta_window_get_outer_rect (window, &titlebar_rect); | ||||
|   meta_window_get_frame_rect (window, &titlebar_rect); | ||||
|   titlebar_rect.height = window->frame->child_y; | ||||
|  | ||||
|   /* Run through the spanning rectangles for the screen and see if one of | ||||
| @@ -9706,7 +9923,8 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, | ||||
|   switch (xev->evtype) | ||||
|     { | ||||
|     case XI_ButtonRelease: | ||||
|       if (xev->detail == 1) | ||||
|       if (xev->detail == 1 || | ||||
|           xev->detail == meta_prefs_get_mouse_button_resize ()) | ||||
|         { | ||||
|           meta_display_check_threshold_reached (window->display, | ||||
|                                                 xev->root_x, | ||||
| @@ -10160,7 +10378,7 @@ warp_grab_pointer (MetaWindow          *window, | ||||
|   /* We may not have done begin_grab_op yet, i.e. may not be in a grab | ||||
|    */ | ||||
|  | ||||
|   meta_window_get_outer_rect (window, &rect); | ||||
|   meta_window_get_frame_rect (window, &rect); | ||||
|  | ||||
|   switch (grab_op) | ||||
|     { | ||||
| @@ -10499,7 +10717,7 @@ meta_window_set_demands_attention (MetaWindow *window) | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       meta_window_get_outer_rect (window, &candidate_rect); | ||||
|       meta_window_get_frame_rect (window, &candidate_rect); | ||||
|  | ||||
|       /* The stack is sorted with the top windows first. */ | ||||
|  | ||||
| @@ -10510,7 +10728,7 @@ meta_window_set_demands_attention (MetaWindow *window) | ||||
|  | ||||
|           if (meta_window_located_on_workspace (other_window, window->workspace)) | ||||
|             { | ||||
|               meta_window_get_outer_rect (other_window, &other_rect); | ||||
|               meta_window_get_frame_rect (other_window, &other_rect); | ||||
|  | ||||
|               if (meta_rectangle_overlap (&candidate_rect, &other_rect)) | ||||
|                 { | ||||
| @@ -10847,24 +11065,15 @@ meta_window_get_gtk_menubar_object_path (MetaWindow *window) | ||||
|  * meta_window_get_compositor_private: | ||||
|  * @window: a #MetaWindow | ||||
|  * | ||||
|  * Gets the compositor's wrapper object for @window. | ||||
|  * | ||||
|  * Return value: (transfer none): the wrapper object. | ||||
|  **/ | ||||
|  * Return value: (transfer none): | ||||
|  */ | ||||
| GObject * | ||||
| meta_window_get_compositor_private (MetaWindow *window) | ||||
| { | ||||
|   if (!window) | ||||
|     return NULL; | ||||
|   return window->compositor_private; | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_window_set_compositor_private (MetaWindow *window, GObject *priv) | ||||
| { | ||||
|   if (!window) | ||||
|     return; | ||||
|   window->compositor_private = priv; | ||||
|   return G_OBJECT (window->core_actor); | ||||
| } | ||||
|  | ||||
| const char * | ||||
| @@ -11214,8 +11423,8 @@ meta_window_compute_tile_match (MetaWindow *window) | ||||
|           bottommost = match; | ||||
|         } | ||||
|  | ||||
|       meta_window_get_outer_rect (bottommost, &bottommost_rect); | ||||
|       meta_window_get_outer_rect (topmost, &topmost_rect); | ||||
|       meta_window_get_frame_rect (bottommost, &bottommost_rect); | ||||
|       meta_window_get_frame_rect (topmost, &topmost_rect); | ||||
|       /* | ||||
|        * If there's a window stacked in between which is partially visible | ||||
|        * behind the topmost tile we don't consider the tiles to match. | ||||
| @@ -11229,7 +11438,7 @@ meta_window_compute_tile_match (MetaWindow *window) | ||||
|               meta_window_get_workspace (above) != meta_window_get_workspace (window)) | ||||
|             continue; | ||||
|  | ||||
|           meta_window_get_outer_rect (above, &above_rect); | ||||
|           meta_window_get_frame_rect (above, &above_rect); | ||||
|  | ||||
|           if (meta_rectangle_overlap (&above_rect, &bottommost_rect) && | ||||
|               meta_rectangle_overlap (&above_rect, &topmost_rect)) | ||||
| @@ -11245,3 +11454,9 @@ meta_window_can_close (MetaWindow *window) | ||||
| { | ||||
|   return window->has_close_func; | ||||
| } | ||||
|  | ||||
| Window | ||||
| meta_window_get_toplevel_xwindow (MetaWindow *window) | ||||
| { | ||||
|   return window->frame ? window->frame->xwindow : window->xwindow; | ||||
| } | ||||
|   | ||||
| @@ -81,6 +81,7 @@ item(TIMESTAMP) | ||||
| item(VERSION) | ||||
| item(ATOM_PAIR) | ||||
| item(BACKLIGHT) | ||||
| item(hotplug_mode_update) | ||||
|  | ||||
| /* Oddities: These are used, and we need atoms for them, | ||||
|  * but when we need all _NET_WM hints (i.e. when we're making | ||||
|   | ||||
| @@ -83,6 +83,8 @@ CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex); | ||||
|  | ||||
| void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex, | ||||
|                                            CoglTexture       *mask_texture); | ||||
| void meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex, | ||||
|                                                  cairo_region_t    *shape_region); | ||||
|  | ||||
| void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex, | ||||
| 					  cairo_region_t    *clip_region); | ||||
|   | ||||
| @@ -60,11 +60,8 @@ struct _MetaWindowActor | ||||
| GType meta_window_actor_get_type (void); | ||||
|  | ||||
| Window             meta_window_actor_get_x_window         (MetaWindowActor *self); | ||||
| gint               meta_window_actor_get_workspace        (MetaWindowActor *self); | ||||
| MetaWindow *       meta_window_actor_get_meta_window      (MetaWindowActor *self); | ||||
| ClutterActor *     meta_window_actor_get_texture          (MetaWindowActor *self); | ||||
| gboolean           meta_window_actor_is_override_redirect (MetaWindowActor *self); | ||||
| gboolean       meta_window_actor_showing_on_its_workspace (MetaWindowActor *self); | ||||
| gboolean       meta_window_actor_is_destroyed (MetaWindowActor *self); | ||||
|  | ||||
| #endif /* META_WINDOW_ACTOR_H */ | ||||
|   | ||||
| @@ -258,6 +258,7 @@ void     meta_prefs_set_ignore_request_hide_titlebar (gboolean whether); | ||||
|  * @META_KEYBINDING_ACTION_MOVE_TO_SIDE_W: FILLME  | ||||
|  * @META_KEYBINDING_ACTION_MOVE_TO_CENTER: FILLME  | ||||
|  * @META_KEYBINDING_ACTION_OVERLAY_KEY: FILLME  | ||||
|  * @META_KEYBINDING_ACTION_ALWAYS_ON_TOP: FILLME  | ||||
|  * @META_KEYBINDING_ACTION_LAST: FILLME  | ||||
|  */ | ||||
| /* XXX FIXME This should be x-macroed, but isn't yet because it would be | ||||
| @@ -351,6 +352,7 @@ typedef enum _MetaKeyBindingAction | ||||
|   META_KEYBINDING_ACTION_MOVE_TO_CENTER, | ||||
|   META_KEYBINDING_ACTION_OVERLAY_KEY, | ||||
|   META_KEYBINDING_ACTION_ISO_NEXT_GROUP, | ||||
|   META_KEYBINDING_ACTION_ALWAYS_ON_TOP, | ||||
|  | ||||
|   META_KEYBINDING_ACTION_LAST | ||||
| } MetaKeyBindingAction; | ||||
|   | ||||
| @@ -100,7 +100,17 @@ gboolean meta_window_is_override_redirect (MetaWindow *window); | ||||
| gboolean meta_window_is_skip_taskbar (MetaWindow *window); | ||||
| MetaRectangle *meta_window_get_rect (MetaWindow *window); | ||||
| void meta_window_get_input_rect (const MetaWindow *window, MetaRectangle *rect); | ||||
| void meta_window_get_outer_rect (const MetaWindow *window, MetaRectangle *rect); | ||||
|  | ||||
| void meta_window_get_frame_rect (const MetaWindow *window, MetaRectangle *rect); | ||||
| void meta_window_get_outer_rect (const MetaWindow *window, MetaRectangle *rect) G_GNUC_DEPRECATED; | ||||
|  | ||||
| void meta_window_client_rect_to_frame_rect (MetaWindow    *window, | ||||
|                                             MetaRectangle *client_rect, | ||||
|                                             MetaRectangle *frame_rect); | ||||
| void meta_window_frame_rect_to_client_rect (MetaWindow    *window, | ||||
|                                             MetaRectangle *frame_rect, | ||||
|                                             MetaRectangle *client_rect); | ||||
|  | ||||
| MetaScreen *meta_window_get_screen (MetaWindow *window); | ||||
| MetaDisplay *meta_window_get_display (MetaWindow *window); | ||||
| Window meta_window_get_xwindow (MetaWindow *window); | ||||
| @@ -144,7 +154,6 @@ void meta_window_change_workspace_by_index (MetaWindow *window, | ||||
| void meta_window_change_workspace          (MetaWindow  *window, | ||||
|                                             MetaWorkspace *workspace); | ||||
| GObject *meta_window_get_compositor_private (MetaWindow *window); | ||||
| void meta_window_set_compositor_private (MetaWindow *window, GObject *priv); | ||||
| void meta_window_configure_notify (MetaWindow *window, XConfigureEvent *event); | ||||
| const char *meta_window_get_role (MetaWindow *window); | ||||
| MetaStackLayer meta_window_get_layer (MetaWindow *window); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user