Compare commits
	
		
			18 Commits
		
	
	
		
			3.27.91
			...
			wip/dnd-su
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					410b37bc53 | ||
| 
						 | 
					6dfdc6d6ec | ||
| 
						 | 
					869d12c36d | ||
| 
						 | 
					827e0c23c5 | ||
| 
						 | 
					9efd96be7b | ||
| 
						 | 
					102d1e62a2 | ||
| 
						 | 
					aba81603b9 | ||
| 
						 | 
					10c6056ce0 | ||
| 
						 | 
					79fdbbfe1a | ||
| 
						 | 
					572727e6e8 | ||
| 
						 | 
					1dbc9e868f | ||
| 
						 | 
					a181ea3cde | ||
| 
						 | 
					78477dd56a | ||
| 
						 | 
					30cc4e1d0a | ||
| 
						 | 
					4b83b031bc | ||
| 
						 | 
					40a85e0e99 | ||
| 
						 | 
					dfde1ff327 | ||
| 
						 | 
					92b7daab61 | 
@@ -35,13 +35,21 @@
 | 
			
		||||
 | 
			
		||||
#include "meta-stage.h"
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  CoglTexture *texture;
 | 
			
		||||
  MetaRectangle current_rect;
 | 
			
		||||
  int current_x, current_y;
 | 
			
		||||
} MetaCursorLayer;
 | 
			
		||||
 | 
			
		||||
struct _MetaCursorRendererPrivate
 | 
			
		||||
{
 | 
			
		||||
  int current_x, current_y;
 | 
			
		||||
  MetaRectangle current_rect;
 | 
			
		||||
  MetaCursorLayer core_layer;
 | 
			
		||||
  MetaCursorLayer dnd_layer;
 | 
			
		||||
 | 
			
		||||
  MetaCursorReference *displayed_cursor;
 | 
			
		||||
  gboolean handled_by_backend;
 | 
			
		||||
  int dnd_surface_offset_x, dnd_surface_offset_y;
 | 
			
		||||
  gboolean cursor_handled_by_backend;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
 | 
			
		||||
 | 
			
		||||
@@ -59,12 +67,19 @@ queue_redraw (MetaCursorRenderer *renderer)
 | 
			
		||||
  if (!stage)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (priv->displayed_cursor && !priv->handled_by_backend)
 | 
			
		||||
    texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, NULL, NULL);
 | 
			
		||||
  /* Pointer cursor */
 | 
			
		||||
  if (!priv->cursor_handled_by_backend)
 | 
			
		||||
    texture = priv->core_layer.texture;
 | 
			
		||||
  else
 | 
			
		||||
    texture = NULL;
 | 
			
		||||
 | 
			
		||||
  meta_stage_set_cursor (META_STAGE (stage), texture, &priv->current_rect);
 | 
			
		||||
  meta_stage_set_cursor (META_STAGE (stage), texture,
 | 
			
		||||
                         &priv->core_layer.current_rect);
 | 
			
		||||
 | 
			
		||||
  /* DnD surface */
 | 
			
		||||
  meta_stage_set_dnd_surface (META_STAGE (stage),
 | 
			
		||||
                              priv->dnd_layer.texture,
 | 
			
		||||
                              &priv->dnd_layer.current_rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
@@ -85,46 +100,76 @@ meta_cursor_renderer_init (MetaCursorRenderer *renderer)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_cursor (MetaCursorRenderer *renderer)
 | 
			
		||||
update_layer (MetaCursorRenderer *renderer,
 | 
			
		||||
              MetaCursorLayer    *layer,
 | 
			
		||||
              CoglTexture        *texture,
 | 
			
		||||
              int                 offset_x,
 | 
			
		||||
              int                 offset_y)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
 | 
			
		||||
  gboolean handled_by_backend;
 | 
			
		||||
  gboolean should_redraw = FALSE;
 | 
			
		||||
  layer->texture = texture;
 | 
			
		||||
 | 
			
		||||
  if (priv->displayed_cursor)
 | 
			
		||||
  if (layer->texture)
 | 
			
		||||
    {
 | 
			
		||||
      CoglTexture *texture;
 | 
			
		||||
      int hot_x, hot_y;
 | 
			
		||||
 | 
			
		||||
      texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, &hot_x, &hot_y);
 | 
			
		||||
 | 
			
		||||
      priv->current_rect.x = priv->current_x - hot_x;
 | 
			
		||||
      priv->current_rect.y = priv->current_y - hot_y;
 | 
			
		||||
      priv->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (texture));
 | 
			
		||||
      priv->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (texture));
 | 
			
		||||
      layer->current_rect.x = layer->current_x + offset_x;
 | 
			
		||||
      layer->current_rect.y = layer->current_y + offset_y;
 | 
			
		||||
      layer->current_rect.width = cogl_texture_get_width (layer->texture);
 | 
			
		||||
      layer->current_rect.height = cogl_texture_get_height (layer->texture);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      priv->current_rect.x = 0;
 | 
			
		||||
      priv->current_rect.y = 0;
 | 
			
		||||
      priv->current_rect.width = 0;
 | 
			
		||||
      priv->current_rect.height = 0;
 | 
			
		||||
      layer->current_rect.x = 0;
 | 
			
		||||
      layer->current_rect.y = 0;
 | 
			
		||||
      layer->current_rect.width = 0;
 | 
			
		||||
      layer->current_rect.height = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
emit_update_cursor (MetaCursorRenderer *renderer,
 | 
			
		||||
                    gboolean            force)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
 | 
			
		||||
  gboolean handled_by_backend, should_redraw = FALSE;
 | 
			
		||||
 | 
			
		||||
  handled_by_backend = META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer);
 | 
			
		||||
  if (handled_by_backend != priv->handled_by_backend)
 | 
			
		||||
 | 
			
		||||
  if (handled_by_backend != priv->cursor_handled_by_backend)
 | 
			
		||||
    {
 | 
			
		||||
      priv->handled_by_backend = handled_by_backend;
 | 
			
		||||
      priv->cursor_handled_by_backend = handled_by_backend;
 | 
			
		||||
      should_redraw = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!handled_by_backend)
 | 
			
		||||
  if (force || !handled_by_backend || priv->dnd_layer.texture)
 | 
			
		||||
    should_redraw = TRUE;
 | 
			
		||||
 | 
			
		||||
  if (should_redraw)
 | 
			
		||||
    queue_redraw (renderer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_cursor (MetaCursorRenderer *renderer)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
 | 
			
		||||
  CoglTexture *texture;
 | 
			
		||||
  int hot_x, hot_y;
 | 
			
		||||
 | 
			
		||||
  /* Cursor layer */
 | 
			
		||||
  if (priv->displayed_cursor)
 | 
			
		||||
    {
 | 
			
		||||
      texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor,
 | 
			
		||||
                                                        &hot_x, &hot_y);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      texture = NULL;
 | 
			
		||||
      hot_x = 0;
 | 
			
		||||
      hot_y = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  update_layer (renderer, &priv->core_layer, texture, -hot_x, -hot_y);
 | 
			
		||||
  emit_update_cursor (renderer, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaCursorRenderer *
 | 
			
		||||
meta_cursor_renderer_new (void)
 | 
			
		||||
{
 | 
			
		||||
@@ -144,6 +189,23 @@ meta_cursor_renderer_set_cursor (MetaCursorRenderer  *renderer,
 | 
			
		||||
  update_cursor (renderer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_renderer_set_dnd_surface (MetaCursorRenderer *renderer,
 | 
			
		||||
                                      CoglTexture        *texture,
 | 
			
		||||
                                      int                 offset_x,
 | 
			
		||||
                                      int                 offset_y)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  priv->dnd_surface_offset_x = offset_x;
 | 
			
		||||
  priv->dnd_surface_offset_y = offset_y;
 | 
			
		||||
 | 
			
		||||
  update_layer (renderer, &priv->dnd_layer, texture, offset_x, offset_y);
 | 
			
		||||
  emit_update_cursor (renderer, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
 | 
			
		||||
                                   int x, int y)
 | 
			
		||||
@@ -152,12 +214,46 @@ meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
 | 
			
		||||
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  priv->current_x = x;
 | 
			
		||||
  priv->current_y = y;
 | 
			
		||||
  priv->core_layer.current_x = x;
 | 
			
		||||
  priv->core_layer.current_y = y;
 | 
			
		||||
 | 
			
		||||
  update_cursor (renderer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_renderer_set_dnd_surface_position (MetaCursorRenderer *renderer,
 | 
			
		||||
                                               int                 x,
 | 
			
		||||
                                               int                 y)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  priv->dnd_layer.current_x = x;
 | 
			
		||||
  priv->dnd_layer.current_y = y;
 | 
			
		||||
 | 
			
		||||
  update_layer (renderer, &priv->dnd_layer, priv->dnd_layer.texture,
 | 
			
		||||
                priv->dnd_surface_offset_x, priv->dnd_surface_offset_y);
 | 
			
		||||
  emit_update_cursor (renderer, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_renderer_dnd_failed (MetaCursorRenderer *renderer,
 | 
			
		||||
                                 int                 dest_x,
 | 
			
		||||
                                 int                 dest_y)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
 | 
			
		||||
  MetaBackend *backend = meta_get_backend ();
 | 
			
		||||
  ClutterActor *stage = meta_backend_get_stage (backend);
 | 
			
		||||
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  if (priv->dnd_layer.texture)
 | 
			
		||||
    meta_stage_dnd_failed (META_STAGE (stage),
 | 
			
		||||
                           dest_x + priv->dnd_surface_offset_x,
 | 
			
		||||
                           dest_y + priv->dnd_surface_offset_y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaCursorReference *
 | 
			
		||||
meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
 | 
			
		||||
{
 | 
			
		||||
@@ -171,5 +267,5 @@ meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
  return &priv->current_rect;
 | 
			
		||||
  return &priv->core_layer.current_rect;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -67,4 +67,14 @@ void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
 | 
			
		||||
MetaCursorReference * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
 | 
			
		||||
const MetaRectangle * meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer);
 | 
			
		||||
 | 
			
		||||
void meta_cursor_renderer_set_dnd_surface (MetaCursorRenderer *renderer,
 | 
			
		||||
                                           CoglTexture        *texture,
 | 
			
		||||
                                           int                 offset_x,
 | 
			
		||||
                                           int                 offset_y);
 | 
			
		||||
void meta_cursor_renderer_set_dnd_surface_position (MetaCursorRenderer *renderer,
 | 
			
		||||
                                                    int x, int y);
 | 
			
		||||
 | 
			
		||||
void meta_cursor_renderer_dnd_failed (MetaCursorRenderer *renderer,
 | 
			
		||||
                                      int dest_x, int dest_y);
 | 
			
		||||
 | 
			
		||||
#endif /* META_CURSOR_RENDERER_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -62,10 +62,20 @@ void     meta_cursor_tracker_set_window_cursor   (MetaCursorTracker   *tracker,
 | 
			
		||||
void     meta_cursor_tracker_unset_window_cursor (MetaCursorTracker   *tracker);
 | 
			
		||||
void     meta_cursor_tracker_set_root_cursor     (MetaCursorTracker   *tracker,
 | 
			
		||||
                                                  MetaCursorReference *cursor);
 | 
			
		||||
void     meta_cursor_tracker_set_dnd_surface     (MetaCursorTracker   *tracker,
 | 
			
		||||
                                                  CoglTexture         *texture,
 | 
			
		||||
                                                  int                  offset_x,
 | 
			
		||||
                                                  int                  offset_y);
 | 
			
		||||
 | 
			
		||||
void     meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
 | 
			
		||||
					      int                new_x,
 | 
			
		||||
					      int                new_y);
 | 
			
		||||
void     meta_cursor_tracker_update_dnd_surface_position (MetaCursorTracker *tracker,
 | 
			
		||||
                                                          int                new_x,
 | 
			
		||||
                                                          int                new_y);
 | 
			
		||||
void     meta_cursor_tracker_dnd_failed (MetaCursorTracker *tracker,
 | 
			
		||||
                                         int                dest_x,
 | 
			
		||||
                                         int                dest_y);
 | 
			
		||||
 | 
			
		||||
MetaCursorReference * meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -358,6 +358,28 @@ meta_cursor_tracker_set_root_cursor (MetaCursorTracker   *tracker,
 | 
			
		||||
  sync_cursor (tracker);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_set_dnd_surface (MetaCursorTracker   *tracker,
 | 
			
		||||
                                     CoglTexture         *texture,
 | 
			
		||||
                                     int                  offset_x,
 | 
			
		||||
                                     int                  offset_y)
 | 
			
		||||
{
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  meta_cursor_renderer_set_dnd_surface (tracker->renderer, texture,
 | 
			
		||||
                                        offset_x, offset_y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_dnd_failed (MetaCursorTracker *tracker,
 | 
			
		||||
                                int                dest_x,
 | 
			
		||||
                                int                dest_y)
 | 
			
		||||
{
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  meta_cursor_renderer_dnd_failed (tracker->renderer, dest_x, dest_y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
 | 
			
		||||
                                     int                new_x,
 | 
			
		||||
@@ -368,6 +390,17 @@ meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
 | 
			
		||||
  meta_cursor_renderer_set_position (tracker->renderer, new_x, new_y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_update_dnd_surface_position (MetaCursorTracker *tracker,
 | 
			
		||||
                                                 int                new_x,
 | 
			
		||||
                                                 int                new_y)
 | 
			
		||||
{
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  meta_cursor_renderer_set_dnd_surface_position (tracker->renderer,
 | 
			
		||||
                                                 new_x, new_y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
get_pointer_position_gdk (int         *x,
 | 
			
		||||
                          int         *y,
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,8 @@
 | 
			
		||||
#include <meta/meta-backend.h>
 | 
			
		||||
#include <meta/util.h>
 | 
			
		||||
 | 
			
		||||
#define DRAG_FAILED_MSECS 500
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  gboolean enabled;
 | 
			
		||||
 | 
			
		||||
@@ -39,8 +41,20 @@ typedef struct {
 | 
			
		||||
  gboolean previous_is_valid;
 | 
			
		||||
} MetaOverlay;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  MetaStage *stage;
 | 
			
		||||
  MetaOverlay overlay;
 | 
			
		||||
  ClutterTimeline *timeline;
 | 
			
		||||
  int orig_x;
 | 
			
		||||
  int orig_y;
 | 
			
		||||
  int dest_x;
 | 
			
		||||
  int dest_y;
 | 
			
		||||
} MetaDragFailedAnimation;
 | 
			
		||||
 | 
			
		||||
struct _MetaStagePrivate {
 | 
			
		||||
  MetaOverlay dnd_overlay;
 | 
			
		||||
  MetaOverlay cursor_overlay;
 | 
			
		||||
  GList *drag_failed_animations;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _MetaStagePrivate MetaStagePrivate;
 | 
			
		||||
 | 
			
		||||
@@ -54,6 +68,15 @@ meta_overlay_init (MetaOverlay *overlay)
 | 
			
		||||
  overlay->pipeline = cogl_pipeline_new (ctx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_overlay_copy (MetaOverlay *src,
 | 
			
		||||
                   MetaOverlay *dst)
 | 
			
		||||
{
 | 
			
		||||
  *dst = *src;
 | 
			
		||||
  dst->pipeline = cogl_pipeline_copy (src->pipeline);
 | 
			
		||||
  dst->texture = src->texture;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_overlay_free (MetaOverlay *overlay)
 | 
			
		||||
{
 | 
			
		||||
@@ -112,6 +135,7 @@ meta_stage_finalize (GObject *object)
 | 
			
		||||
  MetaStage *stage = META_STAGE (object);
 | 
			
		||||
  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
 | 
			
		||||
 | 
			
		||||
  meta_overlay_free (&priv->dnd_overlay);
 | 
			
		||||
  meta_overlay_free (&priv->cursor_overlay);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -120,9 +144,18 @@ meta_stage_paint (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  MetaStage *stage = META_STAGE (actor);
 | 
			
		||||
  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
 | 
			
		||||
  MetaDragFailedAnimation *animation;
 | 
			
		||||
  GList *l;
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor);
 | 
			
		||||
 | 
			
		||||
  for (l = priv->drag_failed_animations; l; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      animation = l->data;
 | 
			
		||||
      meta_overlay_paint (&animation->overlay);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_overlay_paint (&priv->dnd_overlay);
 | 
			
		||||
  meta_overlay_paint (&priv->cursor_overlay);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -142,6 +175,7 @@ meta_stage_init (MetaStage *stage)
 | 
			
		||||
{
 | 
			
		||||
  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
 | 
			
		||||
 | 
			
		||||
  meta_overlay_init (&priv->dnd_overlay);
 | 
			
		||||
  meta_overlay_init (&priv->cursor_overlay);
 | 
			
		||||
 | 
			
		||||
  clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), FALSE);
 | 
			
		||||
@@ -183,6 +217,19 @@ queue_redraw_for_overlay (MetaStage   *stage,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_stage_set_dnd_surface (MetaStage     *stage,
 | 
			
		||||
                            CoglTexture   *texture,
 | 
			
		||||
                            MetaRectangle *rect)
 | 
			
		||||
{
 | 
			
		||||
  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
 | 
			
		||||
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  meta_overlay_set (&priv->dnd_overlay, texture, rect);
 | 
			
		||||
  queue_redraw_for_overlay (stage, &priv->dnd_overlay);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_stage_set_cursor (MetaStage     *stage,
 | 
			
		||||
                       CoglTexture   *texture,
 | 
			
		||||
@@ -195,3 +242,84 @@ meta_stage_set_cursor (MetaStage     *stage,
 | 
			
		||||
  meta_overlay_set (&priv->cursor_overlay, texture, rect);
 | 
			
		||||
  queue_redraw_for_overlay (stage, &priv->cursor_overlay);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
drag_failed_animation_frame_cb (ClutterTimeline *timeline,
 | 
			
		||||
                                guint            pos,
 | 
			
		||||
                                gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
  MetaDragFailedAnimation *data = user_data;
 | 
			
		||||
  gdouble progress = clutter_timeline_get_progress (timeline);
 | 
			
		||||
  CoglColor color;
 | 
			
		||||
 | 
			
		||||
  cogl_color_init_from_4f (&color, 0, 0, 0, 1 - progress);
 | 
			
		||||
  cogl_pipeline_set_layer_combine_constant (data->overlay.pipeline, 0, &color);
 | 
			
		||||
 | 
			
		||||
  data->overlay.current_rect.x = data->orig_x + ((data->dest_x - data->orig_x) * progress);
 | 
			
		||||
  data->overlay.current_rect.y = data->orig_y + ((data->dest_y - data->orig_y) * progress);
 | 
			
		||||
  queue_redraw_for_overlay (data->stage, &data->overlay);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_drag_failed_animation_free (MetaDragFailedAnimation *data)
 | 
			
		||||
{
 | 
			
		||||
  MetaStage *stage = data->stage;
 | 
			
		||||
  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
 | 
			
		||||
 | 
			
		||||
  priv->drag_failed_animations =
 | 
			
		||||
    g_list_remove (priv->drag_failed_animations, data);
 | 
			
		||||
 | 
			
		||||
  g_object_unref (data->timeline);
 | 
			
		||||
  meta_overlay_free (&data->overlay);
 | 
			
		||||
  g_slice_free (MetaDragFailedAnimation, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaDragFailedAnimation *
 | 
			
		||||
meta_drag_failed_animation_new (MetaStage *stage,
 | 
			
		||||
                                int        dest_x,
 | 
			
		||||
                                int        dest_y)
 | 
			
		||||
{
 | 
			
		||||
  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
 | 
			
		||||
  MetaDragFailedAnimation *data;
 | 
			
		||||
 | 
			
		||||
  data = g_slice_new0 (MetaDragFailedAnimation);
 | 
			
		||||
  data->stage = stage;
 | 
			
		||||
  data->orig_x = priv->dnd_overlay.current_rect.x;
 | 
			
		||||
  data->orig_y = priv->dnd_overlay.current_rect.y;
 | 
			
		||||
  data->dest_x = dest_x;
 | 
			
		||||
  data->dest_y = dest_y;
 | 
			
		||||
 | 
			
		||||
  meta_overlay_copy (&priv->dnd_overlay, &data->overlay);
 | 
			
		||||
 | 
			
		||||
  data->timeline = clutter_timeline_new (DRAG_FAILED_MSECS);
 | 
			
		||||
  clutter_timeline_set_progress_mode (data->timeline, CLUTTER_EASE_OUT_CUBIC);
 | 
			
		||||
  g_signal_connect (data->timeline, "new-frame",
 | 
			
		||||
                    G_CALLBACK (drag_failed_animation_frame_cb), data);
 | 
			
		||||
  g_signal_connect_swapped (data->timeline, "completed",
 | 
			
		||||
                            G_CALLBACK (meta_drag_failed_animation_free), data);
 | 
			
		||||
 | 
			
		||||
  priv->drag_failed_animations =
 | 
			
		||||
    g_list_prepend (priv->drag_failed_animations, data);
 | 
			
		||||
 | 
			
		||||
  cogl_pipeline_set_layer_combine (data->overlay.pipeline, 0,
 | 
			
		||||
                                   "RGBA = MODULATE (TEXTURE, CONSTANT[A])",
 | 
			
		||||
                                   NULL);
 | 
			
		||||
  return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_stage_dnd_failed (MetaStage *stage,
 | 
			
		||||
                       int        dest_x,
 | 
			
		||||
                       int        dest_y)
 | 
			
		||||
{
 | 
			
		||||
  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
 | 
			
		||||
  MetaDragFailedAnimation *data;
 | 
			
		||||
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  if (!priv->dnd_overlay.enabled)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  data = meta_drag_failed_animation_new (stage, dest_x, dest_y);
 | 
			
		||||
  clutter_timeline_start (data->timeline);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -51,9 +51,18 @@ GType             meta_stage_get_type                (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
ClutterActor     *meta_stage_new                     (void);
 | 
			
		||||
 | 
			
		||||
void meta_stage_set_dnd_surface (MetaStage     *stage,
 | 
			
		||||
                                 CoglTexture   *texture,
 | 
			
		||||
                                 MetaRectangle *rect);
 | 
			
		||||
 | 
			
		||||
void meta_stage_set_cursor (MetaStage     *stage,
 | 
			
		||||
                            CoglTexture   *texture,
 | 
			
		||||
                            MetaRectangle *rect);
 | 
			
		||||
 | 
			
		||||
void meta_stage_dnd_failed (MetaStage *stage,
 | 
			
		||||
                            int        dest_x,
 | 
			
		||||
                            int        dest_y);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* META_STAGE_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,7 @@
 | 
			
		||||
#include "meta-wayland-seat.h"
 | 
			
		||||
#include "meta-wayland-pointer.h"
 | 
			
		||||
#include "meta-wayland-private.h"
 | 
			
		||||
#include "meta-cursor-tracker-private.h"
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
@@ -46,6 +47,7 @@ struct _MetaWaylandDataSource
 | 
			
		||||
{
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
  struct wl_array mime_types;
 | 
			
		||||
  gboolean has_target;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -67,7 +69,10 @@ data_offer_accept (struct wl_client *client,
 | 
			
		||||
   * this be a wl_data_device request? */
 | 
			
		||||
 | 
			
		||||
  if (offer->source)
 | 
			
		||||
    wl_data_source_send_target (offer->source->resource, mime_type);
 | 
			
		||||
    {
 | 
			
		||||
      wl_data_source_send_target (offer->source->resource, mime_type);
 | 
			
		||||
      offer->source->has_target = mime_type != NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -162,7 +167,7 @@ static struct wl_data_source_interface data_source_interface = {
 | 
			
		||||
  data_source_destroy
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
struct _MetaWaylandDragGrab {
 | 
			
		||||
  MetaWaylandPointerGrab  generic;
 | 
			
		||||
 | 
			
		||||
  MetaWaylandSeat        *seat;
 | 
			
		||||
@@ -177,7 +182,12 @@ typedef struct {
 | 
			
		||||
 | 
			
		||||
  MetaWaylandDataSource  *drag_data_source;
 | 
			
		||||
  struct wl_listener      drag_data_source_listener;
 | 
			
		||||
} MetaWaylandDragGrab;
 | 
			
		||||
 | 
			
		||||
  MetaWaylandSurface     *drag_origin;
 | 
			
		||||
  struct wl_listener      drag_origin_listener;
 | 
			
		||||
 | 
			
		||||
  int                     drag_start_x, drag_start_y;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
destroy_drag_focus (struct wl_listener *listener, void *data)
 | 
			
		||||
@@ -202,6 +212,8 @@ drag_grab_focus (MetaWaylandPointerGrab *grab,
 | 
			
		||||
  if (drag_grab->drag_focus == surface)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  meta_wayland_pointer_set_focus (&seat->pointer, surface, FALSE);
 | 
			
		||||
 | 
			
		||||
  if (drag_grab->drag_focus_data_device)
 | 
			
		||||
    {
 | 
			
		||||
      wl_data_device_send_leave (drag_grab->drag_focus_data_device);
 | 
			
		||||
@@ -241,6 +253,40 @@ drag_grab_focus (MetaWaylandPointerGrab *grab,
 | 
			
		||||
  wl_resource_add_destroy_listener (data_device_resource, &drag_grab->drag_focus_listener);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
drag_grab_update_dnd_surface_position (MetaWaylandDragGrab *drag_grab)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandSeat *seat = drag_grab->seat;
 | 
			
		||||
  ClutterPoint pos;
 | 
			
		||||
 | 
			
		||||
  clutter_input_device_get_coords (seat->pointer.device, NULL, &pos);
 | 
			
		||||
  meta_cursor_tracker_update_dnd_surface_position (seat->pointer.cursor_tracker,
 | 
			
		||||
                                                   (int) pos.x, (int) pos.y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
drag_grab_update_dnd_surface (MetaWaylandDragGrab *drag_grab)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandSurface *surface = drag_grab->drag_surface;
 | 
			
		||||
  MetaWaylandSeat *seat = drag_grab->seat;
 | 
			
		||||
  CoglTexture *texture = NULL;
 | 
			
		||||
  int offset_x, offset_y;
 | 
			
		||||
 | 
			
		||||
  if (surface)
 | 
			
		||||
    {
 | 
			
		||||
      if (surface->buffer)
 | 
			
		||||
        texture = surface->buffer->texture;
 | 
			
		||||
 | 
			
		||||
      offset_x = surface->offset_x;
 | 
			
		||||
      offset_y = surface->offset_y;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    offset_x = offset_y = 0;
 | 
			
		||||
 | 
			
		||||
  meta_cursor_tracker_set_dnd_surface (seat->pointer.cursor_tracker,
 | 
			
		||||
                                       texture, offset_x, offset_y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
drag_grab_motion (MetaWaylandPointerGrab *grab,
 | 
			
		||||
		  const ClutterEvent     *event)
 | 
			
		||||
@@ -248,6 +294,8 @@ drag_grab_motion (MetaWaylandPointerGrab *grab,
 | 
			
		||||
  MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab;
 | 
			
		||||
  wl_fixed_t sx, sy;
 | 
			
		||||
 | 
			
		||||
  drag_grab_update_dnd_surface_position (drag_grab);
 | 
			
		||||
 | 
			
		||||
  if (drag_grab->drag_focus_data_device)
 | 
			
		||||
    {
 | 
			
		||||
      meta_wayland_pointer_get_relative_coordinates (grab->pointer,
 | 
			
		||||
@@ -259,9 +307,38 @@ drag_grab_motion (MetaWaylandPointerGrab *grab,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
data_device_dnd_failed (MetaWaylandDragGrab *drag_grab)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandSurface *surface = drag_grab->drag_origin;
 | 
			
		||||
  MetaWaylandSeat *seat = drag_grab->seat;
 | 
			
		||||
  ClutterPoint dest;
 | 
			
		||||
 | 
			
		||||
  if (drag_grab->drag_origin &&
 | 
			
		||||
      !meta_window_is_hidden (surface->window))
 | 
			
		||||
    {
 | 
			
		||||
      /* Find out the snap back position */
 | 
			
		||||
      clutter_actor_get_transformed_position (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)),
 | 
			
		||||
                                              &dest.x, &dest.y);
 | 
			
		||||
      dest.x += drag_grab->drag_start_x;
 | 
			
		||||
      dest.y += drag_grab->drag_start_y;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    clutter_input_device_get_coords (seat->pointer.device, NULL, &dest);
 | 
			
		||||
 | 
			
		||||
  meta_cursor_tracker_dnd_failed (seat->pointer.cursor_tracker,
 | 
			
		||||
                                  dest.x, dest.y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
 | 
			
		||||
{
 | 
			
		||||
  if (drag_grab->drag_origin)
 | 
			
		||||
    {
 | 
			
		||||
      drag_grab->drag_origin = NULL;
 | 
			
		||||
      wl_list_remove (&drag_grab->drag_origin_listener.link);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (drag_grab->drag_surface)
 | 
			
		||||
    {
 | 
			
		||||
      drag_grab->drag_surface = NULL;
 | 
			
		||||
@@ -269,9 +346,15 @@ data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (drag_grab->drag_data_source)
 | 
			
		||||
    wl_list_remove (&drag_grab->drag_data_source_listener.link);
 | 
			
		||||
    {
 | 
			
		||||
      drag_grab->drag_data_source->has_target = FALSE;
 | 
			
		||||
      wl_list_remove (&drag_grab->drag_data_source_listener.link);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  drag_grab->seat->data_device.current_grab = NULL;
 | 
			
		||||
 | 
			
		||||
  drag_grab_focus (&drag_grab->generic, NULL);
 | 
			
		||||
  drag_grab_update_dnd_surface (drag_grab);
 | 
			
		||||
 | 
			
		||||
  meta_wayland_pointer_end_grab (drag_grab->generic.pointer);
 | 
			
		||||
  g_slice_free (MetaWaylandDragGrab, drag_grab);
 | 
			
		||||
@@ -285,10 +368,15 @@ drag_grab_button (MetaWaylandPointerGrab *grab,
 | 
			
		||||
  MetaWaylandSeat *seat = drag_grab->seat;
 | 
			
		||||
  ClutterEventType event_type = clutter_event_type (event);
 | 
			
		||||
 | 
			
		||||
  if (drag_grab->drag_focus_data_device &&
 | 
			
		||||
      drag_grab->generic.pointer->grab_button == clutter_event_get_button (event) &&
 | 
			
		||||
  if (drag_grab->generic.pointer->grab_button == clutter_event_get_button (event) &&
 | 
			
		||||
      event_type == CLUTTER_BUTTON_RELEASE)
 | 
			
		||||
    wl_data_device_send_drop (drag_grab->drag_focus_data_device);
 | 
			
		||||
    {
 | 
			
		||||
      if (drag_grab->drag_focus_data_device &&
 | 
			
		||||
          drag_grab->drag_data_source->has_target)
 | 
			
		||||
        wl_data_device_send_drop (drag_grab->drag_focus_data_device);
 | 
			
		||||
      else
 | 
			
		||||
        data_device_dnd_failed (drag_grab);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (seat->pointer.button_count == 0 &&
 | 
			
		||||
      event_type == CLUTTER_BUTTON_RELEASE)
 | 
			
		||||
@@ -301,6 +389,16 @@ static const MetaWaylandPointerGrabInterface drag_grab_interface = {
 | 
			
		||||
  drag_grab_button,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
destroy_data_device_origin (struct wl_listener *listener, void *data)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDragGrab *drag_grab =
 | 
			
		||||
    wl_container_of (listener, drag_grab, drag_origin_listener);
 | 
			
		||||
 | 
			
		||||
  drag_grab->drag_origin = NULL;
 | 
			
		||||
  data_device_end_drag_grab (drag_grab);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
destroy_data_device_source (struct wl_listener *listener, void *data)
 | 
			
		||||
{
 | 
			
		||||
@@ -318,6 +416,7 @@ destroy_data_device_icon (struct wl_listener *listener, void *data)
 | 
			
		||||
    wl_container_of (listener, drag_grab, drag_data_source_listener);
 | 
			
		||||
 | 
			
		||||
  drag_grab->drag_surface = NULL;
 | 
			
		||||
  drag_grab_update_dnd_surface (drag_grab);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -329,20 +428,29 @@ data_device_start_drag (struct wl_client *client,
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataDevice *data_device = wl_resource_get_user_data (resource);
 | 
			
		||||
  MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
 | 
			
		||||
  MetaWaylandSurface *surface = NULL;
 | 
			
		||||
  MetaWaylandDragGrab *drag_grab;
 | 
			
		||||
  ClutterPoint pos;
 | 
			
		||||
 | 
			
		||||
  if ((seat->pointer.button_count == 0 ||
 | 
			
		||||
       seat->pointer.grab_serial != serial ||
 | 
			
		||||
       !seat->pointer.focus_surface ||
 | 
			
		||||
       seat->pointer.focus_surface != wl_resource_get_user_data (origin_resource)))
 | 
			
		||||
  if (origin_resource)
 | 
			
		||||
    surface = wl_resource_get_user_data (origin_resource);
 | 
			
		||||
 | 
			
		||||
  if (!surface)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (seat->pointer.button_count == 0 ||
 | 
			
		||||
      seat->pointer.grab_serial != serial ||
 | 
			
		||||
      !seat->pointer.focus_surface ||
 | 
			
		||||
      seat->pointer.focus_surface != surface)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* FIXME: Check that the data source type array isn't empty. */
 | 
			
		||||
 | 
			
		||||
  if (seat->pointer.grab != &seat->pointer.default_grab)
 | 
			
		||||
  if (data_device->current_grab ||
 | 
			
		||||
      seat->pointer.grab != &seat->pointer.default_grab)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  drag_grab = g_slice_new0 (MetaWaylandDragGrab);
 | 
			
		||||
  data_device->current_grab = drag_grab = g_slice_new0 (MetaWaylandDragGrab);
 | 
			
		||||
 | 
			
		||||
  drag_grab->generic.interface = &drag_grab_interface;
 | 
			
		||||
  drag_grab->generic.pointer = &seat->pointer;
 | 
			
		||||
@@ -350,6 +458,17 @@ data_device_start_drag (struct wl_client *client,
 | 
			
		||||
  drag_grab->drag_client = client;
 | 
			
		||||
  drag_grab->seat = seat;
 | 
			
		||||
 | 
			
		||||
  drag_grab->drag_origin = surface;
 | 
			
		||||
  drag_grab->drag_origin_listener.notify = destroy_data_device_origin;
 | 
			
		||||
  wl_resource_add_destroy_listener (origin_resource,
 | 
			
		||||
                                    &drag_grab->drag_origin_listener);
 | 
			
		||||
 | 
			
		||||
  clutter_input_device_get_coords (seat->pointer.device, NULL, &pos);
 | 
			
		||||
  clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)),
 | 
			
		||||
                                       pos.x, pos.y, &pos.x, &pos.y);
 | 
			
		||||
  drag_grab->drag_start_x = pos.x;
 | 
			
		||||
  drag_grab->drag_start_y = pos.y;
 | 
			
		||||
 | 
			
		||||
  if (source_resource)
 | 
			
		||||
    {
 | 
			
		||||
      drag_grab->drag_data_source = wl_resource_get_user_data (source_resource);
 | 
			
		||||
@@ -366,8 +485,10 @@ data_device_start_drag (struct wl_client *client,
 | 
			
		||||
                                        &drag_grab->drag_icon_listener);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_wayland_pointer_set_focus (&seat->pointer, NULL);
 | 
			
		||||
  meta_wayland_pointer_set_focus (&seat->pointer, NULL, TRUE);
 | 
			
		||||
  meta_wayland_pointer_start_grab (&seat->pointer, (MetaWaylandPointerGrab*)drag_grab);
 | 
			
		||||
  drag_grab_update_dnd_surface_position (drag_grab);
 | 
			
		||||
  drag_grab_update_dnd_surface (drag_grab);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -551,3 +672,18 @@ meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device)
 | 
			
		||||
      wl_data_device_send_selection (data_device_resource, offer);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_wayland_data_device_is_dnd_surface (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                                         MetaWaylandSurface    *surface)
 | 
			
		||||
{
 | 
			
		||||
  return data_device->current_grab &&
 | 
			
		||||
    data_device->current_grab->drag_surface == surface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_data_device_update_dnd_surface (MetaWaylandDataDevice *data_device)
 | 
			
		||||
{
 | 
			
		||||
  if (data_device->current_grab)
 | 
			
		||||
    drag_grab_update_dnd_surface (data_device->current_grab);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -27,12 +27,15 @@
 | 
			
		||||
 | 
			
		||||
#include "meta-wayland-types.h"
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaWaylandDragGrab MetaWaylandDragGrab;
 | 
			
		||||
 | 
			
		||||
struct _MetaWaylandDataDevice
 | 
			
		||||
{
 | 
			
		||||
  uint32_t selection_serial;
 | 
			
		||||
  MetaWaylandDataSource *selection_data_source;
 | 
			
		||||
  struct wl_listener selection_data_source_listener;
 | 
			
		||||
  struct wl_list resource_list;
 | 
			
		||||
  MetaWaylandDragGrab *current_grab;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void meta_wayland_data_device_manager_init (MetaWaylandCompositor *compositor);
 | 
			
		||||
@@ -41,4 +44,8 @@ void meta_wayland_data_device_init (MetaWaylandDataDevice *data_device);
 | 
			
		||||
 | 
			
		||||
void meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device);
 | 
			
		||||
 | 
			
		||||
gboolean meta_wayland_data_device_is_dnd_surface (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                                                  MetaWaylandSurface    *surface);
 | 
			
		||||
void meta_wayland_data_device_update_dnd_surface (MetaWaylandDataDevice *data_device);
 | 
			
		||||
 | 
			
		||||
#endif /* META_WAYLAND_DATA_DEVICE_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -95,7 +95,7 @@ pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_surface_listener);
 | 
			
		||||
 | 
			
		||||
  meta_wayland_pointer_set_focus (pointer, NULL);
 | 
			
		||||
  meta_wayland_pointer_set_focus (pointer, NULL, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -107,7 +107,7 @@ default_grab_focus (MetaWaylandPointerGrab *grab,
 | 
			
		||||
  if (pointer->button_count > 0)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  meta_wayland_pointer_set_focus (pointer, surface);
 | 
			
		||||
  meta_wayland_pointer_set_focus (pointer, surface, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -178,7 +178,7 @@ default_grab_button (MetaWaylandPointerGrab *grab,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (pointer->button_count == 0 && event_type == CLUTTER_BUTTON_RELEASE)
 | 
			
		||||
    meta_wayland_pointer_set_focus (pointer, pointer->current);
 | 
			
		||||
    meta_wayland_pointer_set_focus (pointer, pointer->current, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const MetaWaylandPointerGrabInterface default_pointer_grab_interface = {
 | 
			
		||||
@@ -218,7 +218,7 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer,
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_pointer_release (MetaWaylandPointer *pointer)
 | 
			
		||||
{
 | 
			
		||||
  meta_wayland_pointer_set_focus (pointer, NULL);
 | 
			
		||||
  meta_wayland_pointer_set_focus (pointer, NULL, TRUE);
 | 
			
		||||
  set_cursor_surface (pointer, NULL);
 | 
			
		||||
 | 
			
		||||
  pointer->display = NULL;
 | 
			
		||||
@@ -480,7 +480,8 @@ broadcast_focus (MetaWaylandPointer *pointer,
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
 | 
			
		||||
                                MetaWaylandSurface *surface)
 | 
			
		||||
                                MetaWaylandSurface *surface,
 | 
			
		||||
                                gboolean            emit_crossing)
 | 
			
		||||
{
 | 
			
		||||
  if (pointer->display == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
@@ -500,9 +501,12 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
 | 
			
		||||
          struct wl_display *display = wl_client_get_display (client);
 | 
			
		||||
          uint32_t serial = wl_display_next_serial (display);
 | 
			
		||||
 | 
			
		||||
          wl_resource_for_each (resource, l)
 | 
			
		||||
          if (emit_crossing)
 | 
			
		||||
            {
 | 
			
		||||
              wl_pointer_send_leave (resource, serial, pointer->focus_surface->resource);
 | 
			
		||||
              wl_resource_for_each (resource, l)
 | 
			
		||||
                {
 | 
			
		||||
                  wl_pointer_send_leave (resource, serial, pointer->focus_surface->resource);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          move_resources (&pointer->resource_list, &pointer->focus_resource_list);
 | 
			
		||||
@@ -533,7 +537,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
 | 
			
		||||
                                 wl_resource_get_client (pointer->focus_surface->resource));
 | 
			
		||||
 | 
			
		||||
      l = &pointer->focus_resource_list;
 | 
			
		||||
      if (!wl_list_empty (l))
 | 
			
		||||
      if (emit_crossing && !wl_list_empty (l))
 | 
			
		||||
        {
 | 
			
		||||
          struct wl_client *client = wl_resource_get_client (pointer->focus_surface->resource);
 | 
			
		||||
          struct wl_display *display = wl_client_get_display (client);
 | 
			
		||||
@@ -595,9 +599,9 @@ popup_grab_focus (MetaWaylandPointerGrab *grab,
 | 
			
		||||
  /* Popup grabs are in owner-events mode (ie, events for the same client
 | 
			
		||||
     are reported as normal) */
 | 
			
		||||
  if (surface && wl_resource_get_client (surface->resource) == popup_grab->grab_client)
 | 
			
		||||
    meta_wayland_pointer_set_focus (grab->pointer, surface);
 | 
			
		||||
    meta_wayland_pointer_set_focus (grab->pointer, surface, TRUE);
 | 
			
		||||
  else
 | 
			
		||||
    meta_wayland_pointer_set_focus (grab->pointer, NULL);
 | 
			
		||||
    meta_wayland_pointer_set_focus (grab->pointer, NULL, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
@@ -86,7 +86,8 @@ gboolean meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer,
 | 
			
		||||
                                            const ClutterEvent *event);
 | 
			
		||||
 | 
			
		||||
void meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
 | 
			
		||||
                                     MetaWaylandSurface *surface);
 | 
			
		||||
                                     MetaWaylandSurface *surface,
 | 
			
		||||
                                     gboolean            emit_crossing);
 | 
			
		||||
 | 
			
		||||
void meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer,
 | 
			
		||||
                                      MetaWaylandPointerGrab *grab);
 | 
			
		||||
 
 | 
			
		||||
@@ -175,6 +175,13 @@ cursor_surface_commit (MetaWaylandSurface      *surface,
 | 
			
		||||
    meta_wayland_seat_update_cursor_surface (surface->compositor->seat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
dnd_surface_commit (MetaWaylandSurface      *surface,
 | 
			
		||||
                    MetaWaylandPendingState *pending)
 | 
			
		||||
{
 | 
			
		||||
  meta_wayland_data_device_update_dnd_surface (&surface->compositor->seat->data_device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
calculate_surface_window_geometry (MetaWaylandSurface *surface,
 | 
			
		||||
                                   MetaRectangle      *total_geometry,
 | 
			
		||||
@@ -429,6 +436,9 @@ commit_pending_state (MetaWaylandSurface      *surface,
 | 
			
		||||
  if (!cairo_region_is_empty (pending->damage))
 | 
			
		||||
    surface_process_damage (surface, pending->damage);
 | 
			
		||||
 | 
			
		||||
  surface->offset_x += pending->dx;
 | 
			
		||||
  surface->offset_y += pending->dy;
 | 
			
		||||
 | 
			
		||||
  if (pending->opaque_region)
 | 
			
		||||
    {
 | 
			
		||||
      pending->opaque_region = scale_region (pending->opaque_region, surface->scale);
 | 
			
		||||
@@ -442,6 +452,8 @@ commit_pending_state (MetaWaylandSurface      *surface,
 | 
			
		||||
 | 
			
		||||
  if (surface == compositor->seat->pointer.cursor_surface)
 | 
			
		||||
    cursor_surface_commit (surface, pending);
 | 
			
		||||
  else if (meta_wayland_data_device_is_dnd_surface (&compositor->seat->data_device, surface))
 | 
			
		||||
    dnd_surface_commit (surface, pending);
 | 
			
		||||
  else if (surface->window)
 | 
			
		||||
    toplevel_surface_commit (surface, pending);
 | 
			
		||||
  else if (surface->subsurface.resource)
 | 
			
		||||
 
 | 
			
		||||
@@ -115,6 +115,8 @@ struct _MetaWaylandSurface
 | 
			
		||||
    GSList *pending_placement_ops;
 | 
			
		||||
  } sub;
 | 
			
		||||
 | 
			
		||||
  int32_t offset_x, offset_y;
 | 
			
		||||
 | 
			
		||||
  gboolean has_set_geometry;
 | 
			
		||||
 | 
			
		||||
  /* All the pending state that wl_surface.commit will apply. */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user