Compare commits
49 Commits
3.14.0
...
wip/dnd-su
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
410b37bc53 | ||
|
|
6dfdc6d6ec | ||
|
|
869d12c36d | ||
|
|
827e0c23c5 | ||
|
|
9efd96be7b | ||
|
|
102d1e62a2 | ||
|
|
aba81603b9 | ||
|
|
10c6056ce0 | ||
|
|
79fdbbfe1a | ||
|
|
572727e6e8 | ||
|
|
1dbc9e868f | ||
|
|
a181ea3cde | ||
|
|
78477dd56a | ||
|
|
30cc4e1d0a | ||
|
|
4b83b031bc | ||
|
|
40a85e0e99 | ||
|
|
dfde1ff327 | ||
|
|
92b7daab61 | ||
|
|
b735571688 | ||
|
|
5e249ad5eb | ||
|
|
21bffe4aef | ||
|
|
68283df4d9 | ||
|
|
4f3de2ce39 | ||
|
|
9f8b641472 | ||
|
|
a9a21c801c | ||
|
|
482a97466d | ||
|
|
4e14bb9df3 | ||
|
|
df90545258 | ||
|
|
c954f9cc24 | ||
|
|
d06b39d13c | ||
|
|
f3595ebd08 | ||
|
|
1e1ca47ec1 | ||
|
|
2eec11b445 | ||
|
|
8ff4597201 | ||
|
|
d5f2468d88 | ||
|
|
488dd0b402 | ||
|
|
6565bca210 | ||
|
|
60c22b6236 | ||
|
|
d3111a9f07 | ||
|
|
cdfb301200 | ||
|
|
371560c2b6 | ||
|
|
7616881afa | ||
|
|
74c37d49c4 | ||
|
|
d3142b92f0 | ||
|
|
ae2afa7c5e | ||
|
|
4a71621fbc | ||
|
|
565b9d73d5 | ||
|
|
90bd02ff4d | ||
|
|
73ca0efaeb |
@@ -79,7 +79,7 @@ MUTTER_PC_MODULES="
|
|||||||
$CLUTTER_PACKAGE >= 1.19.5
|
$CLUTTER_PACKAGE >= 1.19.5
|
||||||
clutter-egl-1.0
|
clutter-egl-1.0
|
||||||
cogl-1.0 >= 1.17.1
|
cogl-1.0 >= 1.17.1
|
||||||
gbm
|
gbm >= 10.3
|
||||||
upower-glib >= 0.99.0
|
upower-glib >= 0.99.0
|
||||||
gnome-desktop-3.0
|
gnome-desktop-3.0
|
||||||
xcomposite >= 0.2
|
xcomposite >= 0.2
|
||||||
|
|||||||
2028
po/bn_IN.po
2028
po/bn_IN.po
File diff suppressed because it is too large
Load Diff
1300
po/sr@latin.po
1300
po/sr@latin.po
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,7 @@ stackingdir = $(pkgdatadir)/tests/stacking
|
|||||||
dist_stacking_DATA = \
|
dist_stacking_DATA = \
|
||||||
tests/stacking/basic-x11.metatest \
|
tests/stacking/basic-x11.metatest \
|
||||||
tests/stacking/basic-wayland.metatest \
|
tests/stacking/basic-wayland.metatest \
|
||||||
|
tests/stacking/minimized.metatest \
|
||||||
tests/stacking/mixed-windows.metatest \
|
tests/stacking/mixed-windows.metatest \
|
||||||
tests/stacking/override-redirect.metatest
|
tests/stacking/override-redirect.metatest
|
||||||
|
|
||||||
|
|||||||
@@ -35,13 +35,21 @@
|
|||||||
|
|
||||||
#include "meta-stage.h"
|
#include "meta-stage.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CoglTexture *texture;
|
||||||
|
MetaRectangle current_rect;
|
||||||
|
int current_x, current_y;
|
||||||
|
} MetaCursorLayer;
|
||||||
|
|
||||||
struct _MetaCursorRendererPrivate
|
struct _MetaCursorRendererPrivate
|
||||||
{
|
{
|
||||||
int current_x, current_y;
|
MetaCursorLayer core_layer;
|
||||||
MetaRectangle current_rect;
|
MetaCursorLayer dnd_layer;
|
||||||
|
|
||||||
MetaCursorReference *displayed_cursor;
|
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;
|
typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
|
||||||
|
|
||||||
@@ -59,12 +67,19 @@ queue_redraw (MetaCursorRenderer *renderer)
|
|||||||
if (!stage)
|
if (!stage)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (priv->displayed_cursor && !priv->handled_by_backend)
|
/* Pointer cursor */
|
||||||
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, NULL, NULL);
|
if (!priv->cursor_handled_by_backend)
|
||||||
|
texture = priv->core_layer.texture;
|
||||||
else
|
else
|
||||||
texture = NULL;
|
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
|
static gboolean
|
||||||
@@ -85,46 +100,76 @@ meta_cursor_renderer_init (MetaCursorRenderer *renderer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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);
|
layer->texture = texture;
|
||||||
gboolean handled_by_backend;
|
|
||||||
gboolean should_redraw = FALSE;
|
|
||||||
|
|
||||||
if (priv->displayed_cursor)
|
if (layer->texture)
|
||||||
{
|
{
|
||||||
CoglTexture *texture;
|
layer->current_rect.x = layer->current_x + offset_x;
|
||||||
int hot_x, hot_y;
|
layer->current_rect.y = layer->current_y + offset_y;
|
||||||
|
layer->current_rect.width = cogl_texture_get_width (layer->texture);
|
||||||
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, &hot_x, &hot_y);
|
layer->current_rect.height = cogl_texture_get_height (layer->texture);
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
priv->current_rect.x = 0;
|
layer->current_rect.x = 0;
|
||||||
priv->current_rect.y = 0;
|
layer->current_rect.y = 0;
|
||||||
priv->current_rect.width = 0;
|
layer->current_rect.width = 0;
|
||||||
priv->current_rect.height = 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);
|
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;
|
should_redraw = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!handled_by_backend)
|
if (force || !handled_by_backend || priv->dnd_layer.texture)
|
||||||
should_redraw = TRUE;
|
should_redraw = TRUE;
|
||||||
|
|
||||||
if (should_redraw)
|
if (should_redraw)
|
||||||
queue_redraw (renderer);
|
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 *
|
MetaCursorRenderer *
|
||||||
meta_cursor_renderer_new (void)
|
meta_cursor_renderer_new (void)
|
||||||
{
|
{
|
||||||
@@ -144,6 +189,23 @@ meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
|
|||||||
update_cursor (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
|
void
|
||||||
meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
|
meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
|
||||||
int x, int y)
|
int x, int y)
|
||||||
@@ -152,12 +214,46 @@ meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
|
|||||||
|
|
||||||
g_assert (meta_is_wayland_compositor ());
|
g_assert (meta_is_wayland_compositor ());
|
||||||
|
|
||||||
priv->current_x = x;
|
priv->core_layer.current_x = x;
|
||||||
priv->current_y = y;
|
priv->core_layer.current_y = y;
|
||||||
|
|
||||||
update_cursor (renderer);
|
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 *
|
MetaCursorReference *
|
||||||
meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
|
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);
|
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);
|
MetaCursorReference * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
|
||||||
const MetaRectangle * meta_cursor_renderer_get_rect (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 */
|
#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_unset_window_cursor (MetaCursorTracker *tracker);
|
||||||
void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
||||||
MetaCursorReference *cursor);
|
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,
|
void meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
|
||||||
int new_x,
|
int new_x,
|
||||||
int new_y);
|
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);
|
MetaCursorReference * meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker);
|
||||||
|
|
||||||
|
|||||||
@@ -358,6 +358,28 @@ meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
|||||||
sync_cursor (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
|
void
|
||||||
meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
|
meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
|
||||||
int new_x,
|
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);
|
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
|
static void
|
||||||
get_pointer_position_gdk (int *x,
|
get_pointer_position_gdk (int *x,
|
||||||
int *y,
|
int *y,
|
||||||
|
|||||||
@@ -139,35 +139,56 @@ load_cursor_on_client (MetaCursor cursor)
|
|||||||
meta_prefs_get_cursor_size ());
|
meta_prefs_get_cursor_size ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_hardware_cursor_size (uint64_t *cursor_width, uint64_t *cursor_height)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_NATIVE_BACKEND
|
||||||
|
MetaBackend *meta_backend = meta_get_backend ();
|
||||||
|
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
|
||||||
|
|
||||||
|
if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
|
||||||
|
{
|
||||||
|
meta_cursor_renderer_native_get_cursor_size (META_CURSOR_RENDERER_NATIVE (renderer), cursor_width, cursor_height);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm,
|
meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm,
|
||||||
MetaCursorImage *image,
|
MetaCursorImage *image,
|
||||||
uint8_t *pixels,
|
uint8_t *pixels,
|
||||||
int width,
|
uint width,
|
||||||
int height,
|
uint height,
|
||||||
int rowstride,
|
int rowstride,
|
||||||
uint32_t gbm_format)
|
uint32_t gbm_format)
|
||||||
{
|
{
|
||||||
if (width > 64 || height > 64)
|
uint64_t cursor_width, cursor_height;
|
||||||
|
get_hardware_cursor_size (&cursor_width, &cursor_height);
|
||||||
|
|
||||||
|
if (width > cursor_width || height > cursor_height)
|
||||||
{
|
{
|
||||||
meta_warning ("Invalid theme cursor size (must be at most 64x64)\n");
|
meta_warning ("Invalid theme cursor size (must be at most %ux%u)\n",
|
||||||
|
(unsigned int)cursor_width, (unsigned int)cursor_height);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gbm_device_is_format_supported (gbm, gbm_format,
|
if (gbm_device_is_format_supported (gbm, gbm_format,
|
||||||
GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE))
|
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
|
||||||
{
|
{
|
||||||
uint8_t buf[4 * 64 * 64];
|
uint8_t buf[4 * cursor_width * cursor_height];
|
||||||
int i;
|
uint i;
|
||||||
|
|
||||||
image->bo = gbm_bo_create (gbm, 64, 64,
|
image->bo = gbm_bo_create (gbm, cursor_width, cursor_height,
|
||||||
gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
|
gbm_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
|
||||||
|
|
||||||
memset (buf, 0, sizeof(buf));
|
memset (buf, 0, sizeof(buf));
|
||||||
for (i = 0; i < height; i++)
|
for (i = 0; i < height; i++)
|
||||||
memcpy (buf + i * 4 * 64, pixels + i * rowstride, width * 4);
|
memcpy (buf + i * 4 * cursor_width, pixels + i * rowstride, width * 4);
|
||||||
|
|
||||||
gbm_bo_write (image->bo, buf, 64 * 64 * 4);
|
gbm_bo_write (image->bo, buf, cursor_width * cursor_height * 4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
|
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
|
||||||
@@ -191,7 +212,7 @@ static void
|
|||||||
meta_cursor_image_load_from_xcursor_image (MetaCursorImage *image,
|
meta_cursor_image_load_from_xcursor_image (MetaCursorImage *image,
|
||||||
XcursorImage *xc_image)
|
XcursorImage *xc_image)
|
||||||
{
|
{
|
||||||
int width, height, rowstride;
|
uint width, height, rowstride;
|
||||||
CoglPixelFormat cogl_format;
|
CoglPixelFormat cogl_format;
|
||||||
uint32_t gbm_format;
|
uint32_t gbm_format;
|
||||||
ClutterBackend *clutter_backend;
|
ClutterBackend *clutter_backend;
|
||||||
@@ -262,7 +283,8 @@ meta_cursor_image_load_from_buffer (MetaCursorImage *image,
|
|||||||
CoglContext *cogl_context;
|
CoglContext *cogl_context;
|
||||||
struct wl_shm_buffer *shm_buffer;
|
struct wl_shm_buffer *shm_buffer;
|
||||||
uint32_t gbm_format;
|
uint32_t gbm_format;
|
||||||
int width, height;
|
uint64_t cursor_width, cursor_height;
|
||||||
|
uint width, height;
|
||||||
|
|
||||||
image->hot_x = hot_x;
|
image->hot_x = hot_x;
|
||||||
image->hot_y = hot_y;
|
image->hot_y = hot_y;
|
||||||
@@ -313,22 +335,23 @@ meta_cursor_image_load_from_buffer (MetaCursorImage *image,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* HW cursors must be 64x64, but 64x64 is huge, and no cursor theme actually uses
|
|
||||||
that, so themed cursors must be padded with transparent pixels to fill the
|
|
||||||
overlay. This is trivial if we have CPU access to the data, but it's not
|
|
||||||
possible if the buffer is in GPU memory (and possibly tiled too), so if we
|
|
||||||
don't get the right size, we fallback to GL.
|
|
||||||
*/
|
|
||||||
if (width != 64 || height != 64)
|
|
||||||
{
|
|
||||||
meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gbm)
|
if (gbm)
|
||||||
{
|
{
|
||||||
image->bo = gbm_bo_import (gbm, GBM_BO_IMPORT_WL_BUFFER,
|
/* HW cursors have a predefined size (at least 64x64), which usually is bigger than cursor theme
|
||||||
buffer, GBM_BO_USE_CURSOR_64X64);
|
size, so themed cursors must be padded with transparent pixels to fill the
|
||||||
|
overlay. This is trivial if we have CPU access to the data, but it's not
|
||||||
|
possible if the buffer is in GPU memory (and possibly tiled too), so if we
|
||||||
|
don't get the right size, we fallback to GL.
|
||||||
|
*/
|
||||||
|
get_hardware_cursor_size (&cursor_width, &cursor_height);
|
||||||
|
|
||||||
|
if (width != cursor_width || height != cursor_height)
|
||||||
|
{
|
||||||
|
meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
image->bo = gbm_bo_import (gbm, GBM_BO_IMPORT_WL_BUFFER, buffer, GBM_BO_USE_CURSOR);
|
||||||
if (!image->bo)
|
if (!image->bo)
|
||||||
meta_warning ("Importing HW cursor from wl_buffer failed\n");
|
meta_warning ("Importing HW cursor from wl_buffer failed\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,12 +44,6 @@ enum {
|
|||||||
SIGNALS_LAST
|
SIGNALS_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
PROP_0,
|
|
||||||
PROP_POWER_SAVE_MODE,
|
|
||||||
PROP_LAST
|
|
||||||
};
|
|
||||||
|
|
||||||
static int signals[SIGNALS_LAST];
|
static int signals[SIGNALS_LAST];
|
||||||
|
|
||||||
static void meta_monitor_manager_display_config_init (MetaDBusDisplayConfigIface *iface);
|
static void meta_monitor_manager_display_config_init (MetaDBusDisplayConfigIface *iface);
|
||||||
@@ -167,11 +161,39 @@ make_logical_config (MetaMonitorManager *manager)
|
|||||||
manager->monitor_infos = (void*)g_array_free (monitor_infos, FALSE);
|
manager->monitor_infos = (void*)g_array_free (monitor_infos, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
power_save_mode_changed (MetaMonitorManager *manager,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaMonitorManagerClass *klass;
|
||||||
|
int mode = meta_dbus_display_config_get_power_save_mode (META_DBUS_DISPLAY_CONFIG (manager));
|
||||||
|
|
||||||
|
if (mode == META_POWER_SAVE_UNSUPPORTED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* If DPMS is unsupported, force the property back. */
|
||||||
|
if (manager->power_save_mode == META_POWER_SAVE_UNSUPPORTED)
|
||||||
|
{
|
||||||
|
meta_dbus_display_config_set_power_save_mode (META_DBUS_DISPLAY_CONFIG (manager), META_POWER_SAVE_UNSUPPORTED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
klass = META_MONITOR_MANAGER_GET_CLASS (manager);
|
||||||
|
if (klass->set_power_save_mode)
|
||||||
|
klass->set_power_save_mode (manager, mode);
|
||||||
|
|
||||||
|
manager->power_save_mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_monitor_manager_constructed (GObject *object)
|
meta_monitor_manager_constructed (GObject *object)
|
||||||
{
|
{
|
||||||
MetaMonitorManager *manager = META_MONITOR_MANAGER (object);
|
MetaMonitorManager *manager = META_MONITOR_MANAGER (object);
|
||||||
|
|
||||||
|
g_signal_connect_object (manager, "notify::power-save-mode",
|
||||||
|
G_CALLBACK (power_save_mode_changed), manager, 0);
|
||||||
|
|
||||||
manager->in_init = TRUE;
|
manager->in_init = TRUE;
|
||||||
|
|
||||||
manager->config = meta_monitor_config_new ();
|
manager->config = meta_monitor_config_new ();
|
||||||
@@ -214,23 +236,6 @@ meta_monitor_manager_constructed (GObject *object)
|
|||||||
manager->in_init = FALSE;
|
manager->in_init = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
meta_monitor_manager_set_power_save_mode (MetaMonitorManager *manager,
|
|
||||||
MetaPowerSave mode)
|
|
||||||
{
|
|
||||||
MetaMonitorManagerClass *klass;
|
|
||||||
|
|
||||||
if (manager->power_save_mode == META_POWER_SAVE_UNSUPPORTED ||
|
|
||||||
mode == META_POWER_SAVE_UNSUPPORTED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
klass = META_MONITOR_MANAGER_GET_CLASS (manager);
|
|
||||||
if (klass->set_power_save_mode)
|
|
||||||
klass->set_power_save_mode (manager, mode);
|
|
||||||
|
|
||||||
manager->power_save_mode = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
|
meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
|
||||||
int n_old_outputs)
|
int n_old_outputs)
|
||||||
@@ -298,44 +303,6 @@ meta_monitor_manager_dispose (GObject *object)
|
|||||||
G_OBJECT_CLASS (meta_monitor_manager_parent_class)->dispose (object);
|
G_OBJECT_CLASS (meta_monitor_manager_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
meta_monitor_manager_set_property (GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
const GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
MetaMonitorManager *self = META_MONITOR_MANAGER (object);
|
|
||||||
|
|
||||||
switch (prop_id)
|
|
||||||
{
|
|
||||||
case PROP_POWER_SAVE_MODE:
|
|
||||||
meta_monitor_manager_set_power_save_mode (self, g_value_get_int (value));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_monitor_manager_get_property (GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
MetaMonitorManager *self = META_MONITOR_MANAGER (object);
|
|
||||||
|
|
||||||
switch (prop_id)
|
|
||||||
{
|
|
||||||
case PROP_POWER_SAVE_MODE:
|
|
||||||
g_value_set_int (value, self->power_save_mode);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static GBytes *
|
static GBytes *
|
||||||
meta_monitor_manager_real_read_edid (MetaMonitorManager *manager,
|
meta_monitor_manager_real_read_edid (MetaMonitorManager *manager,
|
||||||
MetaOutput *output)
|
MetaOutput *output)
|
||||||
@@ -356,8 +323,6 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
|
|||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
object_class->constructed = meta_monitor_manager_constructed;
|
object_class->constructed = meta_monitor_manager_constructed;
|
||||||
object_class->get_property = meta_monitor_manager_get_property;
|
|
||||||
object_class->set_property = meta_monitor_manager_set_property;
|
|
||||||
object_class->dispose = meta_monitor_manager_dispose;
|
object_class->dispose = meta_monitor_manager_dispose;
|
||||||
object_class->finalize = meta_monitor_manager_finalize;
|
object_class->finalize = meta_monitor_manager_finalize;
|
||||||
|
|
||||||
@@ -371,8 +336,6 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
|
|||||||
0,
|
0,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
G_TYPE_NONE, 0);
|
G_TYPE_NONE, 0);
|
||||||
|
|
||||||
g_object_class_override_property (object_class, PROP_POWER_SAVE_MODE, "power-save-mode");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const double known_diagonals[] = {
|
static const double known_diagonals[] = {
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
#include <meta/meta-backend.h>
|
#include <meta/meta-backend.h>
|
||||||
#include <meta/util.h>
|
#include <meta/util.h>
|
||||||
|
|
||||||
|
#define DRAG_FAILED_MSECS 500
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gboolean enabled;
|
gboolean enabled;
|
||||||
|
|
||||||
@@ -39,8 +41,20 @@ typedef struct {
|
|||||||
gboolean previous_is_valid;
|
gboolean previous_is_valid;
|
||||||
} MetaOverlay;
|
} MetaOverlay;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MetaStage *stage;
|
||||||
|
MetaOverlay overlay;
|
||||||
|
ClutterTimeline *timeline;
|
||||||
|
int orig_x;
|
||||||
|
int orig_y;
|
||||||
|
int dest_x;
|
||||||
|
int dest_y;
|
||||||
|
} MetaDragFailedAnimation;
|
||||||
|
|
||||||
struct _MetaStagePrivate {
|
struct _MetaStagePrivate {
|
||||||
|
MetaOverlay dnd_overlay;
|
||||||
MetaOverlay cursor_overlay;
|
MetaOverlay cursor_overlay;
|
||||||
|
GList *drag_failed_animations;
|
||||||
};
|
};
|
||||||
typedef struct _MetaStagePrivate MetaStagePrivate;
|
typedef struct _MetaStagePrivate MetaStagePrivate;
|
||||||
|
|
||||||
@@ -54,6 +68,15 @@ meta_overlay_init (MetaOverlay *overlay)
|
|||||||
overlay->pipeline = cogl_pipeline_new (ctx);
|
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
|
static void
|
||||||
meta_overlay_free (MetaOverlay *overlay)
|
meta_overlay_free (MetaOverlay *overlay)
|
||||||
{
|
{
|
||||||
@@ -112,6 +135,7 @@ meta_stage_finalize (GObject *object)
|
|||||||
MetaStage *stage = META_STAGE (object);
|
MetaStage *stage = META_STAGE (object);
|
||||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||||
|
|
||||||
|
meta_overlay_free (&priv->dnd_overlay);
|
||||||
meta_overlay_free (&priv->cursor_overlay);
|
meta_overlay_free (&priv->cursor_overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,9 +144,18 @@ meta_stage_paint (ClutterActor *actor)
|
|||||||
{
|
{
|
||||||
MetaStage *stage = META_STAGE (actor);
|
MetaStage *stage = META_STAGE (actor);
|
||||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||||
|
MetaDragFailedAnimation *animation;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor);
|
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);
|
meta_overlay_paint (&priv->cursor_overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,6 +175,7 @@ meta_stage_init (MetaStage *stage)
|
|||||||
{
|
{
|
||||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||||
|
|
||||||
|
meta_overlay_init (&priv->dnd_overlay);
|
||||||
meta_overlay_init (&priv->cursor_overlay);
|
meta_overlay_init (&priv->cursor_overlay);
|
||||||
|
|
||||||
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), FALSE);
|
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
|
void
|
||||||
meta_stage_set_cursor (MetaStage *stage,
|
meta_stage_set_cursor (MetaStage *stage,
|
||||||
CoglTexture *texture,
|
CoglTexture *texture,
|
||||||
@@ -195,3 +242,84 @@ meta_stage_set_cursor (MetaStage *stage,
|
|||||||
meta_overlay_set (&priv->cursor_overlay, texture, rect);
|
meta_overlay_set (&priv->cursor_overlay, texture, rect);
|
||||||
queue_redraw_for_overlay (stage, &priv->cursor_overlay);
|
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);
|
ClutterActor *meta_stage_new (void);
|
||||||
|
|
||||||
|
void meta_stage_set_dnd_surface (MetaStage *stage,
|
||||||
|
CoglTexture *texture,
|
||||||
|
MetaRectangle *rect);
|
||||||
|
|
||||||
void meta_stage_set_cursor (MetaStage *stage,
|
void meta_stage_set_cursor (MetaStage *stage,
|
||||||
CoglTexture *texture,
|
CoglTexture *texture,
|
||||||
MetaRectangle *rect);
|
MetaRectangle *rect);
|
||||||
|
|
||||||
|
void meta_stage_dnd_failed (MetaStage *stage,
|
||||||
|
int dest_x,
|
||||||
|
int dest_y);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* META_STAGE_H */
|
#endif /* META_STAGE_H */
|
||||||
|
|||||||
@@ -27,16 +27,27 @@
|
|||||||
#include "meta-cursor-renderer-native.h"
|
#include "meta-cursor-renderer-native.h"
|
||||||
|
|
||||||
#include <gbm.h>
|
#include <gbm.h>
|
||||||
|
#include <xf86drm.h>
|
||||||
|
|
||||||
#include "meta-cursor-private.h"
|
#include "meta-cursor-private.h"
|
||||||
#include "meta-monitor-manager.h"
|
#include "meta-monitor-manager.h"
|
||||||
|
|
||||||
|
#ifndef DRM_CAP_CURSOR_WIDTH
|
||||||
|
#define DRM_CAP_CURSOR_WIDTH 0x8
|
||||||
|
#endif
|
||||||
|
#ifndef DRM_CAP_CURSOR_HEIGHT
|
||||||
|
#define DRM_CAP_CURSOR_HEIGHT 0x9
|
||||||
|
#endif
|
||||||
|
|
||||||
struct _MetaCursorRendererNativePrivate
|
struct _MetaCursorRendererNativePrivate
|
||||||
{
|
{
|
||||||
gboolean has_hw_cursor;
|
gboolean has_hw_cursor;
|
||||||
|
|
||||||
int drm_fd;
|
int drm_fd;
|
||||||
struct gbm_device *gbm;
|
struct gbm_device *gbm;
|
||||||
|
|
||||||
|
uint64_t cursor_width;
|
||||||
|
uint64_t cursor_height;
|
||||||
};
|
};
|
||||||
typedef struct _MetaCursorRendererNativePrivate MetaCursorRendererNativePrivate;
|
typedef struct _MetaCursorRendererNativePrivate MetaCursorRendererNativePrivate;
|
||||||
|
|
||||||
@@ -71,17 +82,13 @@ set_crtc_cursor (MetaCursorRendererNative *native,
|
|||||||
{
|
{
|
||||||
struct gbm_bo *bo;
|
struct gbm_bo *bo;
|
||||||
union gbm_bo_handle handle;
|
union gbm_bo_handle handle;
|
||||||
int width, height;
|
|
||||||
int hot_x, hot_y;
|
int hot_x, hot_y;
|
||||||
|
|
||||||
bo = meta_cursor_reference_get_gbm_bo (cursor, &hot_x, &hot_y);
|
bo = meta_cursor_reference_get_gbm_bo (cursor, &hot_x, &hot_y);
|
||||||
|
|
||||||
handle = gbm_bo_get_handle (bo);
|
handle = gbm_bo_get_handle (bo);
|
||||||
width = gbm_bo_get_width (bo);
|
|
||||||
height = gbm_bo_get_height (bo);
|
|
||||||
|
|
||||||
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, handle.u32,
|
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, handle.u32,
|
||||||
width, height, hot_x, hot_y);
|
priv->cursor_width, priv->cursor_height, hot_x, hot_y);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -186,6 +193,19 @@ meta_cursor_renderer_native_init (MetaCursorRendererNative *native)
|
|||||||
CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (ctx));
|
CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (ctx));
|
||||||
priv->drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
|
priv->drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
|
||||||
priv->gbm = gbm_create_device (priv->drm_fd);
|
priv->gbm = gbm_create_device (priv->drm_fd);
|
||||||
|
|
||||||
|
uint64_t width, height;
|
||||||
|
if (drmGetCap (priv->drm_fd, DRM_CAP_CURSOR_WIDTH, &width) == 0 &&
|
||||||
|
drmGetCap (priv->drm_fd, DRM_CAP_CURSOR_HEIGHT, &height) == 0)
|
||||||
|
{
|
||||||
|
priv->cursor_width = width;
|
||||||
|
priv->cursor_height = height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
priv->cursor_width = 64;
|
||||||
|
priv->cursor_height = 64;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -198,6 +218,16 @@ meta_cursor_renderer_native_get_gbm_device (MetaCursorRendererNative *native)
|
|||||||
return priv->gbm;
|
return priv->gbm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_cursor_renderer_native_get_cursor_size (MetaCursorRendererNative *native,
|
||||||
|
uint64_t *width, uint64_t *height)
|
||||||
|
{
|
||||||
|
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
|
||||||
|
|
||||||
|
*width = priv->cursor_width;
|
||||||
|
*height = priv->cursor_height;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_cursor_renderer_native_force_update (MetaCursorRendererNative *native)
|
meta_cursor_renderer_native_force_update (MetaCursorRendererNative *native)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ struct _MetaCursorRendererNativeClass
|
|||||||
GType meta_cursor_renderer_native_get_type (void) G_GNUC_CONST;
|
GType meta_cursor_renderer_native_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
struct gbm_device * meta_cursor_renderer_native_get_gbm_device (MetaCursorRendererNative *renderer);
|
struct gbm_device * meta_cursor_renderer_native_get_gbm_device (MetaCursorRendererNative *renderer);
|
||||||
|
void meta_cursor_renderer_native_get_cursor_size (MetaCursorRendererNative *native, uint64_t *width, uint64_t *height);
|
||||||
void meta_cursor_renderer_native_force_update (MetaCursorRendererNative *renderer);
|
void meta_cursor_renderer_native_force_update (MetaCursorRendererNative *renderer);
|
||||||
|
|
||||||
#endif /* META_CURSOR_RENDERER_NATIVE_H */
|
#endif /* META_CURSOR_RENDERER_NATIVE_H */
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ static gboolean
|
|||||||
output_get_boolean_property (MetaMonitorManagerXrandr *manager_xrandr,
|
output_get_boolean_property (MetaMonitorManagerXrandr *manager_xrandr,
|
||||||
MetaOutput *output, const char *propname)
|
MetaOutput *output, const char *propname)
|
||||||
{
|
{
|
||||||
gboolean value;
|
gboolean value = FALSE;
|
||||||
Atom atom, actual_type;
|
Atom atom, actual_type;
|
||||||
int actual_format;
|
int actual_format;
|
||||||
unsigned long nitems, bytes_after;
|
unsigned long nitems, bytes_after;
|
||||||
@@ -158,12 +158,12 @@ output_get_boolean_property (MetaMonitorManagerXrandr *manager_xrandr,
|
|||||||
&actual_type, &actual_format,
|
&actual_type, &actual_format,
|
||||||
&nitems, &bytes_after, &buffer);
|
&nitems, &bytes_after, &buffer);
|
||||||
|
|
||||||
if (actual_type != XA_CARDINAL || actual_format != 32 ||
|
if (actual_type != XA_CARDINAL || actual_format != 32 || nitems < 1)
|
||||||
nitems < 1)
|
goto out;
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
value = ((int*)buffer)[0];
|
value = ((int*)buffer)[0];
|
||||||
|
|
||||||
|
out:
|
||||||
XFree (buffer);
|
XFree (buffer);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@@ -187,7 +187,7 @@ static int
|
|||||||
output_get_backlight_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
output_get_backlight_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||||
MetaOutput *output)
|
MetaOutput *output)
|
||||||
{
|
{
|
||||||
gboolean value;
|
int value = -1;
|
||||||
Atom atom, actual_type;
|
Atom atom, actual_type;
|
||||||
int actual_format;
|
int actual_format;
|
||||||
unsigned long nitems, bytes_after;
|
unsigned long nitems, bytes_after;
|
||||||
@@ -201,14 +201,17 @@ output_get_backlight_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
|||||||
&actual_type, &actual_format,
|
&actual_type, &actual_format,
|
||||||
&nitems, &bytes_after, &buffer);
|
&nitems, &bytes_after, &buffer);
|
||||||
|
|
||||||
if (actual_type != XA_INTEGER || actual_format != 32 ||
|
if (actual_type != XA_INTEGER || actual_format != 32 || nitems < 1)
|
||||||
nitems < 1)
|
goto out;
|
||||||
return -1;
|
|
||||||
|
|
||||||
value = ((int*)buffer)[0];
|
value = ((int*)buffer)[0];
|
||||||
|
|
||||||
|
out:
|
||||||
XFree (buffer);
|
XFree (buffer);
|
||||||
return normalize_backlight (output, value);
|
if (value > 0)
|
||||||
|
return normalize_backlight (output, value);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -185,6 +185,9 @@ file_loaded (GObject *source_object,
|
|||||||
image->texture = texture;
|
image->texture = texture;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
if (pixbuf != NULL)
|
||||||
|
g_object_unref (pixbuf);
|
||||||
|
|
||||||
image->loaded = TRUE;
|
image->loaded = TRUE;
|
||||||
g_signal_emit (image, signals[LOADED], 0);
|
g_signal_emit (image, signals[LOADED], 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -612,9 +612,14 @@ update_onscreen_requirements (MetaWindow *window,
|
|||||||
*/
|
*/
|
||||||
if (window->frame && window->decorated)
|
if (window->frame && window->decorated)
|
||||||
{
|
{
|
||||||
MetaRectangle titlebar_rect;
|
MetaRectangle titlebar_rect, frame_rect;
|
||||||
|
|
||||||
meta_window_get_titlebar_rect (window, &titlebar_rect);
|
meta_window_get_titlebar_rect (window, &titlebar_rect);
|
||||||
|
meta_window_get_frame_rect (window, &frame_rect);
|
||||||
|
|
||||||
|
/* translate into screen coordinates */
|
||||||
|
titlebar_rect.x = frame_rect.x;
|
||||||
|
titlebar_rect.y = frame_rect.y;
|
||||||
|
|
||||||
old = window->require_titlebar_visible;
|
old = window->require_titlebar_visible;
|
||||||
window->require_titlebar_visible =
|
window->require_titlebar_visible =
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ typedef struct MetaEdgeResistanceData MetaEdgeResistanceData;
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
META_LIST_DEFAULT = 0, /* normal windows */
|
META_LIST_DEFAULT = 0, /* normal windows */
|
||||||
META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */
|
META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */
|
||||||
|
META_LIST_SORTED = 1 << 1, /* sort list by mru */
|
||||||
} MetaListWindowsFlags;
|
} MetaListWindowsFlags;
|
||||||
|
|
||||||
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
|
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
|
||||||
|
|||||||
@@ -150,6 +150,9 @@ static void update_cursor_theme (void);
|
|||||||
static void prefs_changed_callback (MetaPreference pref,
|
static void prefs_changed_callback (MetaPreference pref,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
|
static int mru_cmp (gconstpointer a,
|
||||||
|
gconstpointer b);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_display_get_property(GObject *object,
|
meta_display_get_property(GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@@ -1061,6 +1064,9 @@ meta_display_list_windows (MetaDisplay *display,
|
|||||||
tmp = next;
|
tmp = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & META_LIST_SORTED)
|
||||||
|
winlist = g_slist_sort (winlist, mru_cmp);
|
||||||
|
|
||||||
return winlist;
|
return winlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,6 +101,8 @@ typedef struct
|
|||||||
MetaKeyCombo *iso_next_group_combos;
|
MetaKeyCombo *iso_next_group_combos;
|
||||||
int n_iso_next_group_combos;
|
int n_iso_next_group_combos;
|
||||||
|
|
||||||
|
xkb_level_index_t keymap_num_levels;
|
||||||
|
|
||||||
/* Alt+click button grabs */
|
/* Alt+click button grabs */
|
||||||
ClutterModifierType window_grab_modifiers;
|
ClutterModifierType window_grab_modifiers;
|
||||||
} MetaKeyBindingManager;
|
} MetaKeyBindingManager;
|
||||||
|
|||||||
@@ -40,7 +40,11 @@
|
|||||||
#include <meta/prefs.h>
|
#include <meta/prefs.h>
|
||||||
#include "meta-accel-parse.h"
|
#include "meta-accel-parse.h"
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
|
#elif !defined KEY_GRAVE
|
||||||
|
#define KEY_GRAVE 0x29 /* assume the use of xf86-input-keyboard */
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "backends/x11/meta-backend-x11.h"
|
#include "backends/x11/meta-backend-x11.h"
|
||||||
#include "x11/window-x11.h"
|
#include "x11/window-x11.h"
|
||||||
@@ -236,29 +240,19 @@ reload_modmap (MetaKeyBindingManager *keys)
|
|||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
is_keycode_for_keysym (struct xkb_keymap *keymap,
|
is_keycode_for_keysym (struct xkb_keymap *keymap,
|
||||||
|
xkb_layout_index_t layout,
|
||||||
|
xkb_level_index_t level,
|
||||||
xkb_keycode_t keycode,
|
xkb_keycode_t keycode,
|
||||||
xkb_keysym_t keysym)
|
xkb_keysym_t keysym)
|
||||||
{
|
{
|
||||||
xkb_layout_index_t num_layouts, i;
|
const xkb_keysym_t *syms;
|
||||||
|
int num_syms, k;
|
||||||
|
|
||||||
num_layouts = xkb_keymap_num_layouts_for_key (keymap, keycode);
|
num_syms = xkb_keymap_key_get_syms_by_level (keymap, keycode, layout, level, &syms);
|
||||||
for (i = 0; i < num_layouts; i++)
|
for (k = 0; k < num_syms; k++)
|
||||||
{
|
{
|
||||||
xkb_level_index_t num_levels, j;
|
if (syms[k] == keysym)
|
||||||
|
return TRUE;
|
||||||
num_levels = xkb_keymap_num_levels_for_key (keymap, keycode, i);
|
|
||||||
for (j = 0; j < num_levels; j++)
|
|
||||||
{
|
|
||||||
const xkb_keysym_t *syms;
|
|
||||||
int num_syms, k;
|
|
||||||
|
|
||||||
num_syms = xkb_keymap_key_get_syms_by_level (keymap, keycode, i, j, &syms);
|
|
||||||
for (k = 0; k < num_syms; k++)
|
|
||||||
{
|
|
||||||
if (syms[k] == keysym)
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -268,6 +262,8 @@ typedef struct
|
|||||||
{
|
{
|
||||||
GArray *keycodes;
|
GArray *keycodes;
|
||||||
xkb_keysym_t keysym;
|
xkb_keysym_t keysym;
|
||||||
|
xkb_layout_index_t layout;
|
||||||
|
xkb_level_index_t level;
|
||||||
} FindKeysymData;
|
} FindKeysymData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -278,8 +274,10 @@ get_keycodes_for_keysym_iter (struct xkb_keymap *keymap,
|
|||||||
FindKeysymData *search_data = data;
|
FindKeysymData *search_data = data;
|
||||||
GArray *keycodes = search_data->keycodes;
|
GArray *keycodes = search_data->keycodes;
|
||||||
xkb_keysym_t keysym = search_data->keysym;
|
xkb_keysym_t keysym = search_data->keysym;
|
||||||
|
xkb_layout_index_t layout = search_data->layout;
|
||||||
|
xkb_level_index_t level = search_data->level;
|
||||||
|
|
||||||
if (is_keycode_for_keysym (keymap, keycode, keysym))
|
if (is_keycode_for_keysym (keymap, layout, level, keycode, keysym))
|
||||||
g_array_append_val (keycodes, keycode);
|
g_array_append_val (keycodes, keycode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,8 +305,15 @@ get_keycodes_for_keysym (MetaKeyBindingManager *keys,
|
|||||||
{
|
{
|
||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
struct xkb_keymap *keymap = meta_backend_get_keymap (backend);
|
struct xkb_keymap *keymap = meta_backend_get_keymap (backend);
|
||||||
FindKeysymData search_data = { retval, keysym };
|
xkb_layout_index_t i;
|
||||||
xkb_keymap_key_for_each (keymap, get_keycodes_for_keysym_iter, &search_data);
|
xkb_level_index_t j;
|
||||||
|
|
||||||
|
for (i = 0; i < xkb_keymap_num_layouts (keymap); i++)
|
||||||
|
for (j = 0; j < keys->keymap_num_levels; j++)
|
||||||
|
{
|
||||||
|
FindKeysymData search_data = { retval, keysym, i, j };
|
||||||
|
xkb_keymap_key_for_each (keymap, get_keycodes_for_keysym_iter, &search_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -319,7 +324,7 @@ get_keycodes_for_keysym (MetaKeyBindingManager *keys,
|
|||||||
|
|
||||||
static guint
|
static guint
|
||||||
get_first_keycode_for_keysym (MetaKeyBindingManager *keys,
|
get_first_keycode_for_keysym (MetaKeyBindingManager *keys,
|
||||||
guint keysym)
|
guint keysym)
|
||||||
{
|
{
|
||||||
int *keycodes;
|
int *keycodes;
|
||||||
int n_keycodes;
|
int n_keycodes;
|
||||||
@@ -336,6 +341,32 @@ get_first_keycode_for_keysym (MetaKeyBindingManager *keys,
|
|||||||
return keycode;
|
return keycode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
determine_keymap_num_levels_iter (struct xkb_keymap *keymap,
|
||||||
|
xkb_keycode_t keycode,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
xkb_level_index_t *num_levels = data;
|
||||||
|
xkb_layout_index_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < xkb_keymap_num_layouts_for_key (keymap, keycode); i++)
|
||||||
|
{
|
||||||
|
xkb_level_index_t level = xkb_keymap_num_levels_for_key (keymap, keycode, i);
|
||||||
|
if (level > *num_levels)
|
||||||
|
*num_levels = level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
determine_keymap_num_levels (MetaKeyBindingManager *keys)
|
||||||
|
{
|
||||||
|
MetaBackend *backend = meta_get_backend ();
|
||||||
|
struct xkb_keymap *keymap = meta_backend_get_keymap (backend);
|
||||||
|
|
||||||
|
keys->keymap_num_levels = 0;
|
||||||
|
xkb_keymap_key_for_each (keymap, determine_keymap_num_levels_iter, &keys->keymap_num_levels);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reload_iso_next_group_combos (MetaKeyBindingManager *keys)
|
reload_iso_next_group_combos (MetaKeyBindingManager *keys)
|
||||||
{
|
{
|
||||||
@@ -484,6 +515,8 @@ reload_keycodes (MetaKeyBindingManager *keys)
|
|||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||||
"Reloading keycodes for binding tables\n");
|
"Reloading keycodes for binding tables\n");
|
||||||
|
|
||||||
|
determine_keymap_num_levels (keys);
|
||||||
|
|
||||||
if (keys->overlay_key_combo.keysym != 0)
|
if (keys->overlay_key_combo.keysym != 0)
|
||||||
{
|
{
|
||||||
keys->overlay_key_combo.keycode =
|
keys->overlay_key_combo.keycode =
|
||||||
|
|||||||
@@ -1187,7 +1187,6 @@ settings_changed (GSettings *settings,
|
|||||||
{
|
{
|
||||||
/* Unknown preference type. This quite likely simply isn't
|
/* Unknown preference type. This quite likely simply isn't
|
||||||
* a preference we track changes to. */
|
* a preference we track changes to. */
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_variant_unref (value);
|
g_variant_unref (value);
|
||||||
|
|||||||
@@ -1056,10 +1056,6 @@ stack_sync_to_xserver (MetaStack *stack)
|
|||||||
all_root_children_stacked = g_array_new (FALSE, FALSE, sizeof (guint64));
|
all_root_children_stacked = g_array_new (FALSE, FALSE, sizeof (guint64));
|
||||||
x11_hidden_stack_ids = g_array_new (FALSE, FALSE, sizeof (guint64));
|
x11_hidden_stack_ids = g_array_new (FALSE, FALSE, sizeof (guint64));
|
||||||
|
|
||||||
/* The screen guard window sits above all hidden windows and acts as
|
|
||||||
* a barrier to input reaching these windows. */
|
|
||||||
g_array_append_val (x11_hidden_stack_ids, stack->screen->guard_window);
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_STACK, "Top to bottom: ");
|
meta_topic (META_DEBUG_STACK, "Top to bottom: ");
|
||||||
meta_push_no_msg_prefix ();
|
meta_push_no_msg_prefix ();
|
||||||
|
|
||||||
@@ -1107,6 +1103,10 @@ stack_sync_to_xserver (MetaStack *stack)
|
|||||||
meta_topic (META_DEBUG_STACK, "\n");
|
meta_topic (META_DEBUG_STACK, "\n");
|
||||||
meta_pop_no_msg_prefix ();
|
meta_pop_no_msg_prefix ();
|
||||||
|
|
||||||
|
/* The screen guard window sits above all hidden windows and acts as
|
||||||
|
* a barrier to input reaching these windows. */
|
||||||
|
g_array_append_val (x11_hidden_stack_ids, stack->screen->guard_window);
|
||||||
|
|
||||||
/* Sync to server */
|
/* Sync to server */
|
||||||
|
|
||||||
meta_topic (META_DEBUG_STACK, "Restacking %u windows\n",
|
meta_topic (META_DEBUG_STACK, "Restacking %u windows\n",
|
||||||
|
|||||||
@@ -1062,8 +1062,8 @@ _meta_window_shared_new (MetaDisplay *display,
|
|||||||
|
|
||||||
if (window->initial_workspace_set)
|
if (window->initial_workspace_set)
|
||||||
{
|
{
|
||||||
gboolean on_all_workspaces;
|
gboolean on_all_workspaces = window->on_all_workspaces;
|
||||||
MetaWorkspace *workspace;
|
MetaWorkspace *workspace = NULL;
|
||||||
|
|
||||||
if (window->initial_workspace == (int) 0xFFFFFFFF)
|
if (window->initial_workspace == (int) 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
@@ -1077,15 +1077,13 @@ _meta_window_shared_new (MetaDisplay *display,
|
|||||||
window->on_all_workspaces_requested = TRUE;
|
window->on_all_workspaces_requested = TRUE;
|
||||||
|
|
||||||
on_all_workspaces = TRUE;
|
on_all_workspaces = TRUE;
|
||||||
workspace = NULL;
|
|
||||||
}
|
}
|
||||||
else
|
else if (!on_all_workspaces)
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_PLACEMENT,
|
meta_topic (META_DEBUG_PLACEMENT,
|
||||||
"Window %s is initially on space %d\n",
|
"Window %s is initially on space %d\n",
|
||||||
window->desc, window->initial_workspace);
|
window->desc, window->initial_workspace);
|
||||||
|
|
||||||
on_all_workspaces = FALSE;
|
|
||||||
workspace = meta_screen_get_workspace_by_index (window->screen,
|
workspace = meta_screen_get_workspace_by_index (window->screen,
|
||||||
window->initial_workspace);
|
window->initial_workspace);
|
||||||
}
|
}
|
||||||
@@ -1099,9 +1097,9 @@ _meta_window_shared_new (MetaDisplay *display,
|
|||||||
* but appear on other workspaces. override-redirect windows are part
|
* but appear on other workspaces. override-redirect windows are part
|
||||||
* of no workspace.
|
* of no workspace.
|
||||||
*/
|
*/
|
||||||
if (!window->override_redirect)
|
if (!window->override_redirect && window->workspace == NULL)
|
||||||
{
|
{
|
||||||
if (window->workspace == NULL && window->transient_for != NULL)
|
if (window->transient_for != NULL)
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_PLACEMENT,
|
meta_topic (META_DEBUG_PLACEMENT,
|
||||||
"Putting window %s on same workspace as parent %s\n",
|
"Putting window %s on same workspace as parent %s\n",
|
||||||
@@ -1112,7 +1110,15 @@ _meta_window_shared_new (MetaDisplay *display,
|
|||||||
window->transient_for->workspace);
|
window->transient_for->workspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->workspace == NULL)
|
if (window->on_all_workspaces)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_PLACEMENT,
|
||||||
|
"Putting window %s on all workspaces\n",
|
||||||
|
window->desc);
|
||||||
|
|
||||||
|
set_workspace_state (window, TRUE, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_PLACEMENT,
|
meta_topic (META_DEBUG_PLACEMENT,
|
||||||
"Putting window %s on active workspace\n",
|
"Putting window %s on active workspace\n",
|
||||||
@@ -2089,7 +2095,7 @@ windows_overlap (const MetaWindow *w1, const MetaWindow *w2)
|
|||||||
static gboolean
|
static gboolean
|
||||||
window_would_be_covered (const MetaWindow *newbie)
|
window_would_be_covered (const MetaWindow *newbie)
|
||||||
{
|
{
|
||||||
MetaWorkspace *workspace = newbie->workspace;
|
MetaWorkspace *workspace = meta_window_get_workspace ((MetaWindow *)newbie);
|
||||||
GList *tmp, *windows;
|
GList *tmp, *windows;
|
||||||
|
|
||||||
windows = meta_workspace_list_windows (workspace);
|
windows = meta_workspace_list_windows (workspace);
|
||||||
@@ -4291,7 +4297,7 @@ meta_window_focus (MetaWindow *window,
|
|||||||
* - workspace->windows is a list of windows that is located on
|
* - workspace->windows is a list of windows that is located on
|
||||||
* that workspace.
|
* that workspace.
|
||||||
*
|
*
|
||||||
* - If the window is on_all_workspaces, then then
|
* - If the window is on_all_workspaces, then
|
||||||
* window->workspace == NULL, but workspace->windows contains
|
* window->workspace == NULL, but workspace->windows contains
|
||||||
* the window.
|
* the window.
|
||||||
*/
|
*/
|
||||||
@@ -4313,7 +4319,8 @@ set_workspace_state (MetaWindow *window,
|
|||||||
g_return_if_fail ((window->constructing && on_all_workspaces) || window->unmanaging);
|
g_return_if_fail ((window->constructing && on_all_workspaces) || window->unmanaging);
|
||||||
|
|
||||||
if (on_all_workspaces == window->on_all_workspaces &&
|
if (on_all_workspaces == window->on_all_workspaces &&
|
||||||
workspace == window->workspace)
|
workspace == window->workspace &&
|
||||||
|
!window->constructing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (window->workspace)
|
if (window->workspace)
|
||||||
@@ -5385,7 +5392,7 @@ meta_window_shove_titlebar_onscreen (MetaWindow *window)
|
|||||||
gboolean
|
gboolean
|
||||||
meta_window_titlebar_is_onscreen (MetaWindow *window)
|
meta_window_titlebar_is_onscreen (MetaWindow *window)
|
||||||
{
|
{
|
||||||
MetaRectangle titlebar_rect;
|
MetaRectangle titlebar_rect, frame_rect;
|
||||||
GList *onscreen_region;
|
GList *onscreen_region;
|
||||||
gboolean is_onscreen;
|
gboolean is_onscreen;
|
||||||
|
|
||||||
@@ -5400,6 +5407,11 @@ meta_window_titlebar_is_onscreen (MetaWindow *window)
|
|||||||
/* Get the rectangle corresponding to the titlebar */
|
/* Get the rectangle corresponding to the titlebar */
|
||||||
meta_window_get_titlebar_rect (window, &titlebar_rect);
|
meta_window_get_titlebar_rect (window, &titlebar_rect);
|
||||||
|
|
||||||
|
/* Translate into screen coordinates */
|
||||||
|
meta_window_get_frame_rect (window, &frame_rect);
|
||||||
|
titlebar_rect.x = frame_rect.x;
|
||||||
|
titlebar_rect.y = frame_rect.y;
|
||||||
|
|
||||||
/* Run through the spanning rectangles for the screen and see if one of
|
/* Run through the spanning rectangles for the screen and see if one of
|
||||||
* them overlaps with the titlebar sufficiently to consider it onscreen.
|
* them overlaps with the titlebar sufficiently to consider it onscreen.
|
||||||
*/
|
*/
|
||||||
@@ -6719,7 +6731,7 @@ meta_window_set_demands_attention (MetaWindow *window)
|
|||||||
other_window = stack->data;
|
other_window = stack->data;
|
||||||
stack = stack->next;
|
stack = stack->next;
|
||||||
|
|
||||||
if (meta_window_located_on_workspace (other_window, window->workspace))
|
if (meta_window_located_on_workspace (other_window, workspace))
|
||||||
{
|
{
|
||||||
meta_window_get_frame_rect (other_window, &other_rect);
|
meta_window_get_frame_rect (other_window, &other_rect);
|
||||||
|
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ MetaWorkspace*
|
|||||||
meta_workspace_new (MetaScreen *screen)
|
meta_workspace_new (MetaScreen *screen)
|
||||||
{
|
{
|
||||||
MetaWorkspace *workspace;
|
MetaWorkspace *workspace;
|
||||||
|
GSList *windows, *l;
|
||||||
|
|
||||||
workspace = g_object_new (META_TYPE_WORKSPACE, NULL);
|
workspace = g_object_new (META_TYPE_WORKSPACE, NULL);
|
||||||
|
|
||||||
@@ -179,6 +180,13 @@ meta_workspace_new (MetaScreen *screen)
|
|||||||
workspace->windows = NULL;
|
workspace->windows = NULL;
|
||||||
workspace->mru_list = NULL;
|
workspace->mru_list = NULL;
|
||||||
|
|
||||||
|
/* make sure sticky windows are in our mru_list */
|
||||||
|
windows = meta_display_list_windows (screen->display, META_LIST_SORTED);
|
||||||
|
for (l = windows; l; l = l->next)
|
||||||
|
if (meta_window_located_on_workspace (l->data, workspace))
|
||||||
|
meta_workspace_add_window (workspace, l->data);
|
||||||
|
g_slist_free (windows);
|
||||||
|
|
||||||
workspace->work_areas_invalid = TRUE;
|
workspace->work_areas_invalid = TRUE;
|
||||||
workspace->work_area_monitor = NULL;
|
workspace->work_area_monitor = NULL;
|
||||||
workspace->work_area_screen.x = 0;
|
workspace->work_area_screen.x = 0;
|
||||||
@@ -358,7 +366,7 @@ meta_workspace_relocate_windows (MetaWorkspace *workspace,
|
|||||||
{
|
{
|
||||||
MetaWindow *window = l->data;
|
MetaWindow *window = l->data;
|
||||||
|
|
||||||
if (!window->override_redirect)
|
if (!window->on_all_workspaces)
|
||||||
meta_window_change_workspace (window, new_home);
|
meta_window_change_workspace (window, new_home);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
#define META_TYPE_WORKSPACE (meta_workspace_get_type ())
|
#define META_TYPE_WORKSPACE (meta_workspace_get_type ())
|
||||||
#define META_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WORKSPACE, MetaWorkspace))
|
#define META_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WORKSPACE, MetaWorkspace))
|
||||||
#define META_WORKSPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WORKSPACE, MetaWorkspaceClass))
|
#define META_WORKSPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WORKSPACE, MetaWorkspaceClass))
|
||||||
#define META_IS_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_WORKSPACE_TYPE))
|
#define META_IS_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_WORKSPACE))
|
||||||
#define META_IS_WORKSPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WORKSPACE))
|
#define META_IS_WORKSPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WORKSPACE))
|
||||||
#define META_WORKSPACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WORKSPACE, MetaWorkspaceClass))
|
#define META_WORKSPACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WORKSPACE, MetaWorkspaceClass))
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,11 @@ lower <client-id>/<window-id>
|
|||||||
for Wayland clients. (It's also considered discouraged, but supported, for
|
for Wayland clients. (It's also considered discouraged, but supported, for
|
||||||
non-override-redirect X11 clients.)
|
non-override-redirect X11 clients.)
|
||||||
|
|
||||||
|
minimize <client-id>/<window-id>
|
||||||
|
unminimize <client-id>/<window-id>
|
||||||
|
Ask the client to minimize or unminimize the given window ID. This older
|
||||||
|
term for this operation is "iconify".
|
||||||
|
|
||||||
destroy <client-id>/<window-id>
|
destroy <client-id>/<window-id>
|
||||||
Destroy the given window
|
Destroy the given window
|
||||||
|
|
||||||
@@ -80,7 +85,10 @@ wait
|
|||||||
|
|
||||||
assert_stacking <client-id>/<window-id> <client-id>/<window-id> ...
|
assert_stacking <client-id>/<window-id> <client-id>/<window-id> ...
|
||||||
Assert that the list of client windows known to Mutter is as given and in
|
Assert that the list of client windows known to Mutter is as given and in
|
||||||
the given order, bottom to top.
|
the given order, bottom to top. The character '|' can be present in the
|
||||||
|
list of windows to indicate the guard window that separates hidden and
|
||||||
|
visible windows. If '|' isn't present, the guard window is asserted to
|
||||||
|
be below all client windows.
|
||||||
|
|
||||||
This function also queries the X server stack and verifies that Mutter's
|
This function also queries the X server stack and verifies that Mutter's
|
||||||
expectation of the X server stack matches reality.
|
expectation of the X server stack matches reality.
|
||||||
|
|||||||
18
src/tests/stacking/minimized.metatest
Normal file
18
src/tests/stacking/minimized.metatest
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
new_client 1 x11
|
||||||
|
create 1/1
|
||||||
|
show 1/1
|
||||||
|
create 1/2
|
||||||
|
show 1/2
|
||||||
|
wait
|
||||||
|
assert_stacking 1/1 1/2
|
||||||
|
|
||||||
|
minimize 1/2
|
||||||
|
wait
|
||||||
|
assert_stacking 1/2 | 1/1
|
||||||
|
|
||||||
|
# unminimize doesn't work for GTK+ currently, because GTK+ expects
|
||||||
|
# to be able to de-iconify with MapWindow, but the window is already
|
||||||
|
# mapped.
|
||||||
|
activate 1/2
|
||||||
|
wait
|
||||||
|
assert_stacking 1/1 1/2
|
||||||
@@ -12,7 +12,7 @@ assert_stacking 1/1 1/2
|
|||||||
|
|
||||||
lower 1/2
|
lower 1/2
|
||||||
wait
|
wait
|
||||||
assert_stacking 1/2 1/1
|
assert_stacking 1/2 | 1/1
|
||||||
|
|
||||||
raise 1/2
|
raise 1/2
|
||||||
wait
|
wait
|
||||||
|
|||||||
@@ -263,6 +263,34 @@ process_line (const char *line)
|
|||||||
XSyncSetCounter (gdk_x11_display_get_xdisplay (gdk_display_get_default ()),
|
XSyncSetCounter (gdk_x11_display_get_xdisplay (gdk_display_get_default ()),
|
||||||
counter, sync_value);
|
counter, sync_value);
|
||||||
}
|
}
|
||||||
|
else if (strcmp (argv[0], "minimize") == 0)
|
||||||
|
{
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
g_print ("usage: minimize <id>");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *window = lookup_window (argv[1]);
|
||||||
|
if (!window)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
gtk_window_iconify (GTK_WINDOW (window));
|
||||||
|
}
|
||||||
|
else if (strcmp (argv[0], "unminimize") == 0)
|
||||||
|
{
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
g_print ("usage: unminimize <id>");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *window = lookup_window (argv[1]);
|
||||||
|
if (!window)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
gtk_window_deiconify (GTK_WINDOW (window));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_print ("Unknown command %s", argv[0]);
|
g_print ("Unknown command %s", argv[0]);
|
||||||
|
|||||||
@@ -413,6 +413,7 @@ typedef struct {
|
|||||||
AsyncWaiter *waiter;
|
AsyncWaiter *waiter;
|
||||||
guint log_handler_id;
|
guint log_handler_id;
|
||||||
GString *warning_messages;
|
GString *warning_messages;
|
||||||
|
GMainLoop *loop;
|
||||||
} TestCase;
|
} TestCase;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -483,10 +484,21 @@ test_case_new (void)
|
|||||||
|
|
||||||
test->clients = g_hash_table_new (g_str_hash, g_str_equal);
|
test->clients = g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
test->waiter = async_waiter_new ();
|
test->waiter = async_waiter_new ();
|
||||||
|
test->loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
test_case_before_redraw (gpointer data)
|
||||||
|
{
|
||||||
|
TestCase *test = data;
|
||||||
|
|
||||||
|
g_main_loop_quit (test->loop);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
test_case_wait (TestCase *test,
|
test_case_wait (TestCase *test,
|
||||||
GError **error)
|
GError **error)
|
||||||
@@ -494,11 +506,30 @@ test_case_wait (TestCase *test,
|
|||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
gpointer key, value;
|
gpointer key, value;
|
||||||
|
|
||||||
|
/* First have each client set a XSync counter, and wait until
|
||||||
|
* we receive the resulting event - so we know we've received
|
||||||
|
* everything that the client have sent us.
|
||||||
|
*/
|
||||||
g_hash_table_iter_init (&iter, test->clients);
|
g_hash_table_iter_init (&iter, test->clients);
|
||||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||||
if (!test_client_wait (value, error))
|
if (!test_client_wait (value, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
/* Then wait until we've done any outstanding queued up work.
|
||||||
|
* Though we add this as BEFORE_REDRAW, the iteration that runs the
|
||||||
|
* BEFORE_REDRAW idles will proceed on and do the redraw, so we're
|
||||||
|
* waiting until after *all* frame processing.
|
||||||
|
*/
|
||||||
|
meta_later_add (META_LATER_BEFORE_REDRAW,
|
||||||
|
test_case_before_redraw,
|
||||||
|
test,
|
||||||
|
NULL);
|
||||||
|
g_main_loop_run (test->loop);
|
||||||
|
|
||||||
|
/* Then set an XSync counter ourselves and and wait until
|
||||||
|
* we receive the resulting event - this makes sure that we've
|
||||||
|
* received back any X events we generated.
|
||||||
|
*/
|
||||||
async_waiter_set_and_wait (test->waiter);
|
async_waiter_set_and_wait (test->waiter);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -579,6 +610,13 @@ test_case_assert_stacking (TestCase *test,
|
|||||||
else
|
else
|
||||||
g_string_append_printf (stack_string, "(%s)", window->title);
|
g_string_append_printf (stack_string, "(%s)", window->title);
|
||||||
}
|
}
|
||||||
|
else if (windows[i] == display->screen->guard_window)
|
||||||
|
{
|
||||||
|
if (stack_string->len > 0)
|
||||||
|
g_string_append_c (stack_string, ' ');
|
||||||
|
|
||||||
|
g_string_append_c (stack_string, '|');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < n_expected_windows; i++)
|
for (i = 0; i < n_expected_windows; i++)
|
||||||
@@ -589,6 +627,16 @@ test_case_assert_stacking (TestCase *test,
|
|||||||
g_string_append (expected_string, expected_windows[i]);
|
g_string_append (expected_string, expected_windows[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Don't require '| ' as a prefix if there are no hidden windows - we
|
||||||
|
* remove the prefix from the actual string instead of adding it to the
|
||||||
|
* expected string for clarity of the error message
|
||||||
|
*/
|
||||||
|
if (index (expected_string->str, '|') == NULL && stack_string->str[0] == '|')
|
||||||
|
{
|
||||||
|
g_string_erase (stack_string,
|
||||||
|
0, stack_string->str[1] == ' ' ? 2 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (strcmp (expected_string->str, stack_string->str) != 0)
|
if (strcmp (expected_string->str, stack_string->str) != 0)
|
||||||
{
|
{
|
||||||
g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED,
|
g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED,
|
||||||
@@ -725,6 +773,8 @@ test_case_do (TestCase *test,
|
|||||||
strcmp (argv[0], "activate") == 0 ||
|
strcmp (argv[0], "activate") == 0 ||
|
||||||
strcmp (argv[0], "raise") == 0 ||
|
strcmp (argv[0], "raise") == 0 ||
|
||||||
strcmp (argv[0], "lower") == 0 ||
|
strcmp (argv[0], "lower") == 0 ||
|
||||||
|
strcmp (argv[0], "minimize") == 0 ||
|
||||||
|
strcmp (argv[0], "unminimize") == 0 ||
|
||||||
strcmp (argv[0], "destroy") == 0)
|
strcmp (argv[0], "destroy") == 0)
|
||||||
{
|
{
|
||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
@@ -766,6 +816,7 @@ test_case_do (TestCase *test,
|
|||||||
{
|
{
|
||||||
if (!test_case_assert_stacking (test, argv + 1, argc - 1, error))
|
if (!test_case_assert_stacking (test, argv + 1, argc - 1, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!test_case_check_xserver_stacking (test, error))
|
if (!test_case_check_xserver_stacking (test, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#include "meta-wayland-seat.h"
|
#include "meta-wayland-seat.h"
|
||||||
#include "meta-wayland-pointer.h"
|
#include "meta-wayland-pointer.h"
|
||||||
#include "meta-wayland-private.h"
|
#include "meta-wayland-private.h"
|
||||||
|
#include "meta-cursor-tracker-private.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -46,6 +47,7 @@ struct _MetaWaylandDataSource
|
|||||||
{
|
{
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
struct wl_array mime_types;
|
struct wl_array mime_types;
|
||||||
|
gboolean has_target;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -67,7 +69,10 @@ data_offer_accept (struct wl_client *client,
|
|||||||
* this be a wl_data_device request? */
|
* this be a wl_data_device request? */
|
||||||
|
|
||||||
if (offer->source)
|
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
|
static void
|
||||||
@@ -162,7 +167,7 @@ static struct wl_data_source_interface data_source_interface = {
|
|||||||
data_source_destroy
|
data_source_destroy
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
struct _MetaWaylandDragGrab {
|
||||||
MetaWaylandPointerGrab generic;
|
MetaWaylandPointerGrab generic;
|
||||||
|
|
||||||
MetaWaylandSeat *seat;
|
MetaWaylandSeat *seat;
|
||||||
@@ -177,7 +182,12 @@ typedef struct {
|
|||||||
|
|
||||||
MetaWaylandDataSource *drag_data_source;
|
MetaWaylandDataSource *drag_data_source;
|
||||||
struct wl_listener drag_data_source_listener;
|
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
|
static void
|
||||||
destroy_drag_focus (struct wl_listener *listener, void *data)
|
destroy_drag_focus (struct wl_listener *listener, void *data)
|
||||||
@@ -202,6 +212,8 @@ drag_grab_focus (MetaWaylandPointerGrab *grab,
|
|||||||
if (drag_grab->drag_focus == surface)
|
if (drag_grab->drag_focus == surface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
meta_wayland_pointer_set_focus (&seat->pointer, surface, FALSE);
|
||||||
|
|
||||||
if (drag_grab->drag_focus_data_device)
|
if (drag_grab->drag_focus_data_device)
|
||||||
{
|
{
|
||||||
wl_data_device_send_leave (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);
|
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
|
static void
|
||||||
drag_grab_motion (MetaWaylandPointerGrab *grab,
|
drag_grab_motion (MetaWaylandPointerGrab *grab,
|
||||||
const ClutterEvent *event)
|
const ClutterEvent *event)
|
||||||
@@ -248,6 +294,8 @@ drag_grab_motion (MetaWaylandPointerGrab *grab,
|
|||||||
MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab;
|
MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab;
|
||||||
wl_fixed_t sx, sy;
|
wl_fixed_t sx, sy;
|
||||||
|
|
||||||
|
drag_grab_update_dnd_surface_position (drag_grab);
|
||||||
|
|
||||||
if (drag_grab->drag_focus_data_device)
|
if (drag_grab->drag_focus_data_device)
|
||||||
{
|
{
|
||||||
meta_wayland_pointer_get_relative_coordinates (grab->pointer,
|
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
|
static void
|
||||||
data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
|
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)
|
if (drag_grab->drag_surface)
|
||||||
{
|
{
|
||||||
drag_grab->drag_surface = NULL;
|
drag_grab->drag_surface = NULL;
|
||||||
@@ -269,9 +346,15 @@ data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (drag_grab->drag_data_source)
|
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_focus (&drag_grab->generic, NULL);
|
||||||
|
drag_grab_update_dnd_surface (drag_grab);
|
||||||
|
|
||||||
meta_wayland_pointer_end_grab (drag_grab->generic.pointer);
|
meta_wayland_pointer_end_grab (drag_grab->generic.pointer);
|
||||||
g_slice_free (MetaWaylandDragGrab, drag_grab);
|
g_slice_free (MetaWaylandDragGrab, drag_grab);
|
||||||
@@ -285,10 +368,15 @@ drag_grab_button (MetaWaylandPointerGrab *grab,
|
|||||||
MetaWaylandSeat *seat = drag_grab->seat;
|
MetaWaylandSeat *seat = drag_grab->seat;
|
||||||
ClutterEventType event_type = clutter_event_type (event);
|
ClutterEventType event_type = clutter_event_type (event);
|
||||||
|
|
||||||
if (drag_grab->drag_focus_data_device &&
|
if (drag_grab->generic.pointer->grab_button == clutter_event_get_button (event) &&
|
||||||
drag_grab->generic.pointer->grab_button == clutter_event_get_button (event) &&
|
|
||||||
event_type == CLUTTER_BUTTON_RELEASE)
|
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 &&
|
if (seat->pointer.button_count == 0 &&
|
||||||
event_type == CLUTTER_BUTTON_RELEASE)
|
event_type == CLUTTER_BUTTON_RELEASE)
|
||||||
@@ -301,6 +389,16 @@ static const MetaWaylandPointerGrabInterface drag_grab_interface = {
|
|||||||
drag_grab_button,
|
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
|
static void
|
||||||
destroy_data_device_source (struct wl_listener *listener, void *data)
|
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);
|
wl_container_of (listener, drag_grab, drag_data_source_listener);
|
||||||
|
|
||||||
drag_grab->drag_surface = NULL;
|
drag_grab->drag_surface = NULL;
|
||||||
|
drag_grab_update_dnd_surface (drag_grab);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -329,20 +428,29 @@ data_device_start_drag (struct wl_client *client,
|
|||||||
{
|
{
|
||||||
MetaWaylandDataDevice *data_device = wl_resource_get_user_data (resource);
|
MetaWaylandDataDevice *data_device = wl_resource_get_user_data (resource);
|
||||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
||||||
|
MetaWaylandSurface *surface = NULL;
|
||||||
MetaWaylandDragGrab *drag_grab;
|
MetaWaylandDragGrab *drag_grab;
|
||||||
|
ClutterPoint pos;
|
||||||
|
|
||||||
if ((seat->pointer.button_count == 0 ||
|
if (origin_resource)
|
||||||
seat->pointer.grab_serial != serial ||
|
surface = wl_resource_get_user_data (origin_resource);
|
||||||
!seat->pointer.focus_surface ||
|
|
||||||
seat->pointer.focus_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;
|
return;
|
||||||
|
|
||||||
/* FIXME: Check that the data source type array isn't empty. */
|
/* 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;
|
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.interface = &drag_grab_interface;
|
||||||
drag_grab->generic.pointer = &seat->pointer;
|
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->drag_client = client;
|
||||||
drag_grab->seat = seat;
|
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)
|
if (source_resource)
|
||||||
{
|
{
|
||||||
drag_grab->drag_data_source = wl_resource_get_user_data (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);
|
&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);
|
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
|
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);
|
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"
|
#include "meta-wayland-types.h"
|
||||||
|
|
||||||
|
typedef struct _MetaWaylandDragGrab MetaWaylandDragGrab;
|
||||||
|
|
||||||
struct _MetaWaylandDataDevice
|
struct _MetaWaylandDataDevice
|
||||||
{
|
{
|
||||||
uint32_t selection_serial;
|
uint32_t selection_serial;
|
||||||
MetaWaylandDataSource *selection_data_source;
|
MetaWaylandDataSource *selection_data_source;
|
||||||
struct wl_listener selection_data_source_listener;
|
struct wl_listener selection_data_source_listener;
|
||||||
struct wl_list resource_list;
|
struct wl_list resource_list;
|
||||||
|
MetaWaylandDragGrab *current_grab;
|
||||||
};
|
};
|
||||||
|
|
||||||
void meta_wayland_data_device_manager_init (MetaWaylandCompositor *compositor);
|
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);
|
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 */
|
#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);
|
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
|
static void
|
||||||
@@ -107,7 +107,7 @@ default_grab_focus (MetaWaylandPointerGrab *grab,
|
|||||||
if (pointer->button_count > 0)
|
if (pointer->button_count > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
meta_wayland_pointer_set_focus (pointer, surface);
|
meta_wayland_pointer_set_focus (pointer, surface, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -178,7 +178,7 @@ default_grab_button (MetaWaylandPointerGrab *grab,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pointer->button_count == 0 && event_type == CLUTTER_BUTTON_RELEASE)
|
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 = {
|
static const MetaWaylandPointerGrabInterface default_pointer_grab_interface = {
|
||||||
@@ -218,7 +218,7 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer,
|
|||||||
void
|
void
|
||||||
meta_wayland_pointer_release (MetaWaylandPointer *pointer)
|
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);
|
set_cursor_surface (pointer, NULL);
|
||||||
|
|
||||||
pointer->display = NULL;
|
pointer->display = NULL;
|
||||||
@@ -480,7 +480,8 @@ broadcast_focus (MetaWaylandPointer *pointer,
|
|||||||
|
|
||||||
void
|
void
|
||||||
meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||||
MetaWaylandSurface *surface)
|
MetaWaylandSurface *surface,
|
||||||
|
gboolean emit_crossing)
|
||||||
{
|
{
|
||||||
if (pointer->display == NULL)
|
if (pointer->display == NULL)
|
||||||
return;
|
return;
|
||||||
@@ -500,9 +501,12 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
|||||||
struct wl_display *display = wl_client_get_display (client);
|
struct wl_display *display = wl_client_get_display (client);
|
||||||
uint32_t serial = wl_display_next_serial (display);
|
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);
|
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));
|
wl_resource_get_client (pointer->focus_surface->resource));
|
||||||
|
|
||||||
l = &pointer->focus_resource_list;
|
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_client *client = wl_resource_get_client (pointer->focus_surface->resource);
|
||||||
struct wl_display *display = wl_client_get_display (client);
|
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
|
/* Popup grabs are in owner-events mode (ie, events for the same client
|
||||||
are reported as normal) */
|
are reported as normal) */
|
||||||
if (surface && wl_resource_get_client (surface->resource) == popup_grab->grab_client)
|
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
|
else
|
||||||
meta_wayland_pointer_set_focus (grab->pointer, NULL);
|
meta_wayland_pointer_set_focus (grab->pointer, NULL, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -86,7 +86,8 @@ gboolean meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer,
|
|||||||
const ClutterEvent *event);
|
const ClutterEvent *event);
|
||||||
|
|
||||||
void meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
void meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||||
MetaWaylandSurface *surface);
|
MetaWaylandSurface *surface,
|
||||||
|
gboolean emit_crossing);
|
||||||
|
|
||||||
void meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer,
|
void meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer,
|
||||||
MetaWaylandPointerGrab *grab);
|
MetaWaylandPointerGrab *grab);
|
||||||
|
|||||||
@@ -175,6 +175,13 @@ cursor_surface_commit (MetaWaylandSurface *surface,
|
|||||||
meta_wayland_seat_update_cursor_surface (surface->compositor->seat);
|
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
|
static void
|
||||||
calculate_surface_window_geometry (MetaWaylandSurface *surface,
|
calculate_surface_window_geometry (MetaWaylandSurface *surface,
|
||||||
MetaRectangle *total_geometry,
|
MetaRectangle *total_geometry,
|
||||||
@@ -429,6 +436,9 @@ commit_pending_state (MetaWaylandSurface *surface,
|
|||||||
if (!cairo_region_is_empty (pending->damage))
|
if (!cairo_region_is_empty (pending->damage))
|
||||||
surface_process_damage (surface, pending->damage);
|
surface_process_damage (surface, pending->damage);
|
||||||
|
|
||||||
|
surface->offset_x += pending->dx;
|
||||||
|
surface->offset_y += pending->dy;
|
||||||
|
|
||||||
if (pending->opaque_region)
|
if (pending->opaque_region)
|
||||||
{
|
{
|
||||||
pending->opaque_region = scale_region (pending->opaque_region, surface->scale);
|
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)
|
if (surface == compositor->seat->pointer.cursor_surface)
|
||||||
cursor_surface_commit (surface, pending);
|
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)
|
else if (surface->window)
|
||||||
toplevel_surface_commit (surface, pending);
|
toplevel_surface_commit (surface, pending);
|
||||||
else if (surface->subsurface.resource)
|
else if (surface->subsurface.resource)
|
||||||
@@ -1441,12 +1453,15 @@ bind_gtk_shell (struct wl_client *client,
|
|||||||
guint32 id)
|
guint32 id)
|
||||||
{
|
{
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
|
uint32_t capabilities = 0;
|
||||||
|
|
||||||
resource = wl_resource_create (client, >k_shell_interface, version, id);
|
resource = wl_resource_create (client, >k_shell_interface, version, id);
|
||||||
wl_resource_set_implementation (resource, &meta_wayland_gtk_shell_interface, data, NULL);
|
wl_resource_set_implementation (resource, &meta_wayland_gtk_shell_interface, data, NULL);
|
||||||
|
|
||||||
/* FIXME: ask the plugin */
|
if (!meta_prefs_get_show_fallback_app_menu ())
|
||||||
gtk_shell_send_capabilities (resource, GTK_SHELL_CAPABILITY_GLOBAL_APP_MENU);
|
capabilities = GTK_SHELL_CAPABILITY_GLOBAL_APP_MENU;
|
||||||
|
|
||||||
|
gtk_shell_send_capabilities (resource, capabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -115,6 +115,8 @@ struct _MetaWaylandSurface
|
|||||||
GSList *pending_placement_ops;
|
GSList *pending_placement_ops;
|
||||||
} sub;
|
} sub;
|
||||||
|
|
||||||
|
int32_t offset_x, offset_y;
|
||||||
|
|
||||||
gboolean has_set_geometry;
|
gboolean has_set_geometry;
|
||||||
|
|
||||||
/* All the pending state that wl_surface.commit will apply. */
|
/* All the pending state that wl_surface.commit will apply. */
|
||||||
|
|||||||
Reference in New Issue
Block a user