Compare commits
	
		
			4 Commits
		
	
	
		
			wip/carlos
			...
			wip/surfac
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | a3a2109c0c | ||
|   | bdbeafc222 | ||
|   | 89ca36818a | ||
|   | fe1a58b459 | 
| @@ -940,6 +940,18 @@ meta_compositor_window_opacity_changed (MetaCompositor *compositor, | ||||
|   meta_window_actor_update_opacity (window_actor); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_compositor_window_surface_changed (MetaCompositor *compositor, | ||||
|                                         MetaWindow     *window) | ||||
| { | ||||
|   MetaWindowActor *window_actor; | ||||
|   window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); | ||||
|   if (!window_actor) | ||||
|     return; | ||||
|  | ||||
|   meta_window_actor_update_surface (window_actor); | ||||
| } | ||||
|  | ||||
| /* Clutter makes the assumption that there is only one X window | ||||
|  * per stage, which is a valid assumption to make for a generic | ||||
|  * application toolkit. As such, it will ignore any events sent | ||||
|   | ||||
| @@ -26,8 +26,8 @@ struct _MetaSurfaceActorPrivate | ||||
|   cairo_region_t *input_region; | ||||
|  | ||||
|   /* Freeze/thaw accounting */ | ||||
|   guint freeze_count; | ||||
|   guint needs_damage_all : 1; | ||||
|   guint frozen : 1; | ||||
| }; | ||||
|  | ||||
| static void cullable_iface_init (MetaCullableInterface *iface); | ||||
| @@ -223,7 +223,7 @@ static gboolean | ||||
| is_frozen (MetaSurfaceActor *self) | ||||
| { | ||||
|   MetaSurfaceActorPrivate *priv = self->priv; | ||||
|   return (priv->freeze_count > 0); | ||||
|   return priv->frozen; | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -274,31 +274,19 @@ meta_surface_actor_is_visible (MetaSurfaceActor *self) | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_surface_actor_freeze (MetaSurfaceActor *self) | ||||
| meta_surface_actor_set_frozen (MetaSurfaceActor *self, | ||||
|                                gboolean          frozen) | ||||
| { | ||||
|   MetaSurfaceActorPrivate *priv = self->priv; | ||||
|  | ||||
|   priv->freeze_count ++; | ||||
| } | ||||
|   priv->frozen = frozen; | ||||
|  | ||||
| void | ||||
| meta_surface_actor_thaw (MetaSurfaceActor *self) | ||||
| { | ||||
|   MetaSurfaceActorPrivate *priv = self->priv; | ||||
|  | ||||
|   if (priv->freeze_count == 0) | ||||
|   if (!frozen && priv->needs_damage_all) | ||||
|     { | ||||
|       g_critical ("Error in freeze/thaw accounting."); | ||||
|       return; | ||||
|     } | ||||
|       /* Since we ignore damage events while a window is frozen for certain effects | ||||
|        * we may need to issue an update_area() covering the whole pixmap if we | ||||
|        * don't know what real damage has happened. */ | ||||
|  | ||||
|   priv->freeze_count --; | ||||
|  | ||||
|   /* Since we ignore damage events while a window is frozen for certain effects | ||||
|    * we may need to issue an update_area() covering the whole pixmap if we | ||||
|    * don't know what real damage has happened. */ | ||||
|   if (priv->needs_damage_all) | ||||
|     { | ||||
|       meta_surface_actor_process_damage (self, 0, 0, | ||||
|                                          clutter_actor_get_width (CLUTTER_ACTOR (priv->texture)), | ||||
|                                          clutter_actor_get_height (CLUTTER_ACTOR (priv->texture))); | ||||
| @@ -306,12 +294,6 @@ meta_surface_actor_thaw (MetaSurfaceActor *self) | ||||
|     } | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_surface_actor_is_frozen (MetaSurfaceActor *self) | ||||
| { | ||||
|   return is_frozen (self); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_surface_actor_should_unredirect (MetaSurfaceActor *self) | ||||
| { | ||||
|   | ||||
| @@ -69,9 +69,8 @@ void meta_surface_actor_pre_paint (MetaSurfaceActor *actor); | ||||
| gboolean meta_surface_actor_is_argb32 (MetaSurfaceActor *actor); | ||||
| gboolean meta_surface_actor_is_visible (MetaSurfaceActor *actor); | ||||
|  | ||||
| void meta_surface_actor_freeze (MetaSurfaceActor *actor); | ||||
| void meta_surface_actor_thaw (MetaSurfaceActor *actor); | ||||
| gboolean meta_surface_actor_is_frozen (MetaSurfaceActor *actor); | ||||
| void meta_surface_actor_set_frozen (MetaSurfaceActor *actor, | ||||
|                                     gboolean          frozen); | ||||
|  | ||||
| gboolean meta_surface_actor_should_unredirect (MetaSurfaceActor *actor); | ||||
| void meta_surface_actor_set_unredirected (MetaSurfaceActor *actor, | ||||
|   | ||||
| @@ -63,5 +63,6 @@ void meta_window_actor_effect_completed (MetaWindowActor *actor, | ||||
|                                          gulong           event); | ||||
|  | ||||
| MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self); | ||||
| void meta_window_actor_update_surface (MetaWindowActor *self); | ||||
|  | ||||
| #endif /* META_WINDOW_ACTOR_PRIVATE_H */ | ||||
|   | ||||
| @@ -84,6 +84,7 @@ struct _MetaWindowActorPrivate | ||||
|  | ||||
|   /* List of FrameData for recent frames */ | ||||
|   GList            *frames; | ||||
|   guint             freeze_count; | ||||
|  | ||||
|   guint		    visible                : 1; | ||||
|   guint		    disposed               : 1; | ||||
| @@ -253,7 +254,15 @@ static gboolean | ||||
| is_argb32 (MetaWindowActor *self) | ||||
| { | ||||
|   MetaWindowActorPrivate *priv = self->priv; | ||||
|   return meta_surface_actor_is_argb32 (priv->surface); | ||||
|  | ||||
|   /* assume we're argb until we get the window (because | ||||
|      in practice we're drawing nothing, so we're fully | ||||
|      transparent) | ||||
|   */ | ||||
|   if (priv->surface) | ||||
|     return meta_surface_actor_is_argb32 (priv->surface); | ||||
|   else | ||||
|     return TRUE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| @@ -269,14 +278,19 @@ static gboolean | ||||
| is_frozen (MetaWindowActor *self) | ||||
| { | ||||
|   MetaWindowActorPrivate *priv = self->priv; | ||||
|   return meta_surface_actor_is_frozen (priv->surface); | ||||
|  | ||||
|   return priv->surface == NULL || priv->freeze_count > 0; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_window_actor_freeze (MetaWindowActor *self) | ||||
| { | ||||
|   MetaWindowActorPrivate *priv = self->priv; | ||||
|   meta_surface_actor_freeze (priv->surface); | ||||
|  | ||||
|   if (priv->freeze_count == 0 && priv->surface) | ||||
|     meta_surface_actor_set_frozen (priv->surface, TRUE); | ||||
|  | ||||
|   priv->freeze_count ++; | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -284,11 +298,16 @@ meta_window_actor_thaw (MetaWindowActor *self) | ||||
| { | ||||
|   MetaWindowActorPrivate *priv = self->priv; | ||||
|  | ||||
|   meta_surface_actor_thaw (priv->surface); | ||||
|   if (priv->freeze_count <= 0) | ||||
|     g_error ("Error in freeze/thaw accounting"); | ||||
|  | ||||
|   if (is_frozen (self)) | ||||
|   priv->freeze_count--; | ||||
|   if (priv->freeze_count > 0) | ||||
|     return; | ||||
|  | ||||
|   if (priv->surface) | ||||
|     meta_surface_actor_set_frozen (priv->surface, FALSE); | ||||
|  | ||||
|   /* We sometimes ignore moves and resizes on frozen windows */ | ||||
|   meta_window_actor_sync_actor_geometry (self, FALSE); | ||||
|  | ||||
| @@ -326,14 +345,13 @@ set_surface (MetaWindowActor  *self, | ||||
|  | ||||
|       /* If the previous surface actor was frozen, start out | ||||
|        * frozen as well... */ | ||||
|       if (priv->updates_frozen) | ||||
|         meta_surface_actor_freeze (priv->surface); | ||||
|       meta_surface_actor_set_frozen (priv->surface, priv->freeze_count > 0); | ||||
|  | ||||
|       meta_window_actor_update_shape (self); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| void | ||||
| meta_window_actor_update_surface (MetaWindowActor *self) | ||||
| { | ||||
|   MetaWindowActorPrivate *priv = self->priv; | ||||
| @@ -342,8 +360,10 @@ meta_window_actor_update_surface (MetaWindowActor *self) | ||||
|  | ||||
|   if (window->surface) | ||||
|     surface_actor = window->surface->surface_actor; | ||||
|   else | ||||
|   else if (!meta_is_wayland_compositor ()) | ||||
|     surface_actor = meta_surface_actor_x11_new (window); | ||||
|   else | ||||
|     surface_actor = NULL; | ||||
|  | ||||
|   set_surface (self, surface_actor); | ||||
| } | ||||
| @@ -650,8 +670,11 @@ meta_window_actor_get_paint_volume (ClutterActor       *actor, | ||||
|  | ||||
|   meta_window_actor_get_shape_bounds (self, &bounds); | ||||
|  | ||||
|   if (meta_surface_actor_get_unobscured_bounds (priv->surface, &unobscured_bounds)) | ||||
|     gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds); | ||||
|   if (priv->surface) | ||||
|     { | ||||
|       if (meta_surface_actor_get_unobscured_bounds (priv->surface, &unobscured_bounds)) | ||||
|         gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds); | ||||
|     } | ||||
|  | ||||
|   if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow) | ||||
|     { | ||||
| @@ -762,21 +785,26 @@ meta_window_actor_get_meta_window (MetaWindowActor *self) | ||||
|  * meta_window_actor_get_texture: | ||||
|  * @self: a #MetaWindowActor | ||||
|  * | ||||
|  * Gets the ClutterActor that is used to display the contents of the window | ||||
|  * Gets the ClutterActor that is used to display the contents of the window, | ||||
|  * or NULL if no texture is shown yet, because the window is not mapped. | ||||
|  * | ||||
|  * Return value: (transfer none): the #ClutterActor for the contents | ||||
|  */ | ||||
| ClutterActor * | ||||
| meta_window_actor_get_texture (MetaWindowActor *self) | ||||
| { | ||||
|   return CLUTTER_ACTOR (meta_surface_actor_get_texture (self->priv->surface)); | ||||
|   if (self->priv->surface) | ||||
|     return CLUTTER_ACTOR (meta_surface_actor_get_texture (self->priv->surface)); | ||||
|   else | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_window_actor_get_surface: | ||||
|  * @self: a #MetaWindowActor | ||||
|  * | ||||
|  * Gets the MetaSurfaceActor that draws the content of this window | ||||
|  * Gets the MetaSurfaceActor that draws the content of this window, | ||||
|  * or NULL if there is no surface yet associated with this window. | ||||
|  * | ||||
|  * Return value: (transfer none): the #MetaSurfaceActor for the contents | ||||
|  */ | ||||
| @@ -875,7 +903,12 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self, | ||||
|  | ||||
|   if (!priv->repaint_scheduled) | ||||
|     { | ||||
|       gboolean is_obscured = meta_surface_actor_is_obscured (priv->surface); | ||||
|       gboolean is_obscured; | ||||
|  | ||||
|       if (priv->surface) | ||||
|         is_obscured = meta_surface_actor_is_obscured (priv->surface); | ||||
|       else | ||||
|         is_obscured = FALSE; | ||||
|  | ||||
|       /* A frame was marked by the client without actually doing any | ||||
|        * damage or any unobscured, or while we had the window frozen | ||||
| @@ -891,9 +924,12 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self, | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           const cairo_rectangle_int_t clip = { 0, 0, 1, 1 }; | ||||
|           clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (priv->surface), &clip); | ||||
|           priv->repaint_scheduled = TRUE; | ||||
|           if (priv->surface) | ||||
|             { | ||||
|               const cairo_rectangle_int_t clip = { 0, 0, 1, 1 }; | ||||
|               clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (priv->surface), &clip); | ||||
|               priv->repaint_scheduled = TRUE; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1066,7 +1102,10 @@ gboolean | ||||
| meta_window_actor_should_unredirect (MetaWindowActor *self) | ||||
| { | ||||
|   MetaWindowActorPrivate *priv = self->priv; | ||||
|   return meta_surface_actor_should_unredirect (priv->surface); | ||||
|   if (priv->surface) | ||||
|     return meta_surface_actor_should_unredirect (priv->surface); | ||||
|   else | ||||
|     return FALSE; | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -1074,6 +1113,8 @@ meta_window_actor_set_unredirected (MetaWindowActor *self, | ||||
|                                     gboolean         unredirected) | ||||
| { | ||||
|   MetaWindowActorPrivate *priv = self->priv; | ||||
|  | ||||
|   g_assert(priv->surface); /* because otherwise should_unredirect() is FALSE */ | ||||
|   meta_surface_actor_set_unredirected (priv->surface, unredirected); | ||||
| } | ||||
|  | ||||
| @@ -1519,11 +1560,12 @@ meta_window_actor_process_x11_damage (MetaWindowActor    *self, | ||||
| { | ||||
|   MetaWindowActorPrivate *priv = self->priv; | ||||
|  | ||||
|   meta_surface_actor_process_damage (priv->surface, | ||||
|                                      event->area.x, | ||||
|                                      event->area.y, | ||||
|                                      event->area.width, | ||||
|                                      event->area.height); | ||||
|   if (priv->surface) | ||||
|     meta_surface_actor_process_damage (priv->surface, | ||||
|                                        event->area.x, | ||||
|                                        event->area.y, | ||||
|                                        event->area.width, | ||||
|                                        event->area.height); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -1718,21 +1760,27 @@ meta_window_actor_update_input_region (MetaWindowActor       *self, | ||||
|   MetaWindowActorPrivate *priv = self->priv; | ||||
|   cairo_region_t *region = NULL; | ||||
|  | ||||
|   if (priv->window->frame != NULL && priv->window->input_region != NULL) | ||||
|   if (priv->window->frame != 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 | ||||
|       /* client area 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_union_rectangle (region, client_area); | ||||
|       cairo_region_translate (region, client_area->x, client_area->y); | ||||
|     } | ||||
|   else if (priv->window->input_region != NULL) | ||||
|   else if (priv->window->shape_region != NULL || | ||||
|            priv->window->input_region != NULL) | ||||
|     { | ||||
|       region = cairo_region_reference (priv->window->input_region); | ||||
|       if (priv->window->shape_region != NULL) | ||||
|         { | ||||
|           region = cairo_region_copy (priv->window->shape_region); | ||||
|  | ||||
|           if (priv->window->input_region != NULL) | ||||
|             cairo_region_intersect (region, priv->window->input_region); | ||||
|         } | ||||
|       else | ||||
|         region = cairo_region_reference (priv->window->input_region); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
| @@ -2026,7 +2074,8 @@ meta_window_actor_update_opacity (MetaWindowActor *self) | ||||
|   MetaWindowActorPrivate *priv = self->priv; | ||||
|   MetaWindow *window = priv->window; | ||||
|  | ||||
|   clutter_actor_set_opacity (CLUTTER_ACTOR (self->priv->surface), window->opacity); | ||||
|   if (priv->surface) | ||||
|     clutter_actor_set_opacity (CLUTTER_ACTOR (priv->surface), window->opacity); | ||||
| } | ||||
|  | ||||
| void | ||||
|   | ||||
| @@ -350,11 +350,43 @@ meta_window_set_input_region (MetaWindow     *window, | ||||
|     meta_compositor_window_shape_changed (window->display->compositor, window); | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| /* Print out a region; useful for debugging */ | ||||
| static void | ||||
| print_region (cairo_region_t *region) | ||||
| { | ||||
|   int n_rects; | ||||
|   int i; | ||||
|  | ||||
|   n_rects = cairo_region_num_rectangles (region); | ||||
|   g_print ("["); | ||||
|   for (i = 0; i < n_rects; i++) | ||||
|     { | ||||
|       cairo_rectangle_int_t rect; | ||||
|       cairo_region_get_rectangle (region, i, &rect); | ||||
|       g_print ("+%d+%dx%dx%d ", | ||||
|                rect.x, rect.y, rect.width, rect.height); | ||||
|     } | ||||
|   g_print ("]\n"); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| void | ||||
| meta_window_x11_update_input_region (MetaWindow *window) | ||||
| { | ||||
|   cairo_region_t *region = NULL; | ||||
|  | ||||
|   /* Decorated windows don't have an input region, because | ||||
|      we don't shape the frame to match the client windows | ||||
|      (so the events are blocked by the frame anyway) | ||||
|   */ | ||||
|   if (window->decorated) | ||||
|     { | ||||
|       if (window->input_region) | ||||
|         meta_window_set_input_region (window, NULL); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
| #ifdef HAVE_SHAPE | ||||
|   if (META_DISPLAY_HAS_SHAPE (window->display)) | ||||
|     { | ||||
| @@ -363,17 +395,6 @@ meta_window_x11_update_input_region (MetaWindow *window) | ||||
|       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, | ||||
| @@ -388,10 +409,10 @@ meta_window_x11_update_input_region (MetaWindow *window) | ||||
|         { | ||||
|           if (n_rects > 1 || | ||||
|               (n_rects == 1 && | ||||
|                (rects[0].x != x_bounding || | ||||
|                 rects[0].y != y_bounding || | ||||
|                 rects[0].width != w_bounding || | ||||
|                 rects[0].height != h_bounding))) | ||||
|                (rects[0].x != 0 || | ||||
|                 rects[0].y != 0 || | ||||
|                 rects[0].width != window->rect.width || | ||||
|                 rects[0].height != window->rect.height))) | ||||
|             region = region_create_from_x_rectangles (rects, n_rects); | ||||
|  | ||||
|           XFree (rects); | ||||
| @@ -1453,6 +1474,11 @@ meta_window_x11_new (MetaDisplay       *display, | ||||
|     XISelectEvents (display->xdisplay, xwindow, &mask, 1); | ||||
|   } | ||||
|  | ||||
| #ifdef HAVE_SHAPE | ||||
|   if (META_DISPLAY_HAS_SHAPE (display)) | ||||
|     XShapeSelectInput (display->xdisplay, xwindow, ShapeNotifyMask); | ||||
| #endif | ||||
|  | ||||
|   /* Get rid of any borders */ | ||||
|   if (attrs.border_width != 0) | ||||
|     XSetWindowBorderWidth (display->xdisplay, xwindow, 0); | ||||
|   | ||||
| @@ -66,6 +66,8 @@ void meta_compositor_window_shape_changed (MetaCompositor *compositor, | ||||
|                                            MetaWindow     *window); | ||||
| void meta_compositor_window_opacity_changed (MetaCompositor *compositor, | ||||
|                                              MetaWindow     *window); | ||||
| void meta_compositor_window_surface_changed (MetaCompositor *compositor, | ||||
|                                              MetaWindow     *window); | ||||
|  | ||||
| gboolean meta_compositor_process_event (MetaCompositor *compositor, | ||||
|                                         XEvent         *event, | ||||
|   | ||||
| @@ -51,6 +51,8 @@ xserver_set_window_id (struct wl_client *client, | ||||
|  | ||||
|   surface->window = window; | ||||
|   window->surface = surface; | ||||
|  | ||||
|   meta_compositor_window_surface_changed (display->compositor, window); | ||||
| } | ||||
|  | ||||
| static const struct xserver_interface xserver_implementation = { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user