Compare commits
14 Commits
wip/carlos
...
gbsneto/pa
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5a4ade857a | ||
![]() |
cc75fc88ee | ||
![]() |
68ec9ac017 | ||
![]() |
8dcac664fa | ||
![]() |
2fb3db7659 | ||
![]() |
7d82cdeea3 | ||
![]() |
e2e7296612 | ||
![]() |
8685de9607 | ||
![]() |
a8a3c1017f | ||
![]() |
5d19aee23a | ||
![]() |
4270eef16e | ||
![]() |
b443bd42ac | ||
![]() |
267503b5f3 | ||
![]() |
a3d9f987c8 |
@@ -841,6 +841,7 @@ struct _ClutterActorPrivate
|
||||
guint needs_x_expand : 1;
|
||||
guint needs_y_expand : 1;
|
||||
guint needs_paint_volume_update : 1;
|
||||
guint had_effects_on_last_paint_volume_update : 1;
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -17485,7 +17486,7 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
|
||||
*/
|
||||
effects = _clutter_meta_group_peek_metas (priv->effects);
|
||||
for (l = effects;
|
||||
l != NULL || (l != NULL && l->data != priv->current_effect);
|
||||
l != NULL && l->data != priv->current_effect;
|
||||
l = l->next)
|
||||
{
|
||||
if (!_clutter_effect_get_paint_volume (l->data, pv))
|
||||
@@ -17521,6 +17522,32 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_clutter_actor_has_active_paint_volume_override_effects (ClutterActor *self)
|
||||
{
|
||||
const GList *l;
|
||||
|
||||
if (self->priv->effects == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* We just need to all effects current effect to see
|
||||
* if anyone wants to override the paint volume. If so, then
|
||||
* we need to recompute, since the paint volume returned can
|
||||
* change from call to call. */
|
||||
for (l = _clutter_meta_group_peek_metas (self->priv->effects);
|
||||
l != NULL;
|
||||
l = l->next)
|
||||
{
|
||||
ClutterEffect *effect = l->data;
|
||||
|
||||
if (clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)) &&
|
||||
_clutter_effect_has_custom_paint_volume (effect))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* The public clutter_actor_get_paint_volume API returns a const
|
||||
* pointer since we return a pointer directly to the cached
|
||||
* PaintVolume associated with the actor and don't want the user to
|
||||
@@ -17531,17 +17558,33 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
|
||||
static ClutterPaintVolume *
|
||||
_clutter_actor_get_paint_volume_mutable (ClutterActor *self)
|
||||
{
|
||||
gboolean has_paint_volume_override_effects;
|
||||
ClutterActorPrivate *priv;
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
has_paint_volume_override_effects = _clutter_actor_has_active_paint_volume_override_effects (self);
|
||||
|
||||
if (priv->paint_volume_valid)
|
||||
{
|
||||
if (!priv->needs_paint_volume_update)
|
||||
/* If effects are applied, the actor paint volume
|
||||
* needs to be recomputed on each paint, since those
|
||||
* paint volumes could change over the duration of the
|
||||
* effect.
|
||||
*
|
||||
* We also need to update the paint volume if we went
|
||||
* from having effects to not having effects on the last
|
||||
* paint volume update. */
|
||||
if (!priv->needs_paint_volume_update &&
|
||||
priv->current_effect == NULL &&
|
||||
!has_paint_volume_override_effects &&
|
||||
!priv->had_effects_on_last_paint_volume_update)
|
||||
return &priv->paint_volume;
|
||||
clutter_paint_volume_free (&priv->paint_volume);
|
||||
}
|
||||
|
||||
priv->had_effects_on_last_paint_volume_update = has_paint_volume_override_effects;
|
||||
|
||||
if (_clutter_actor_get_paint_volume_real (self, &priv->paint_volume))
|
||||
{
|
||||
priv->paint_volume_valid = TRUE;
|
||||
|
@@ -9,6 +9,7 @@ gboolean _clutter_effect_pre_paint (ClutterEffect
|
||||
void _clutter_effect_post_paint (ClutterEffect *effect);
|
||||
gboolean _clutter_effect_get_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume);
|
||||
gboolean _clutter_effect_has_custom_paint_volume (ClutterEffect *effect);
|
||||
void _clutter_effect_paint (ClutterEffect *effect,
|
||||
ClutterEffectPaintFlags flags);
|
||||
void _clutter_effect_pick (ClutterEffect *effect,
|
||||
|
@@ -308,6 +308,14 @@ _clutter_effect_get_paint_volume (ClutterEffect *effect,
|
||||
return CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume (effect, volume);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_effect_has_custom_paint_volume (ClutterEffect *effect)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE);
|
||||
|
||||
return CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume != clutter_effect_real_get_paint_volume;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_effect_queue_repaint:
|
||||
* @effect: A #ClutterEffect which needs redrawing
|
||||
|
@@ -820,8 +820,8 @@ clutter_text_node_draw (ClutterPaintNode *node)
|
||||
}
|
||||
|
||||
cogl_pango_render_layout (tnode->layout,
|
||||
op->op.texrect[0],
|
||||
op->op.texrect[1],
|
||||
op->op.texrect[4],
|
||||
op->op.texrect[5],
|
||||
&tnode->color,
|
||||
0);
|
||||
|
||||
|
@@ -1746,7 +1746,8 @@ add_selection_rectangle_to_path (ClutterText *text,
|
||||
|
||||
/* Draws the selected text, its background, and the cursor */
|
||||
static void
|
||||
selection_paint (ClutterText *self)
|
||||
paint_selection (ClutterText *self,
|
||||
ClutterPaintNode *node)
|
||||
{
|
||||
ClutterTextPrivate *priv = self->priv;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (self);
|
||||
@@ -1758,33 +1759,59 @@ selection_paint (ClutterText *self)
|
||||
|
||||
if (priv->position == priv->selection_bound)
|
||||
{
|
||||
g_autoptr(ClutterPaintNode) cursor_node = NULL;
|
||||
|
||||
/* No selection, just draw the cursor */
|
||||
if (priv->cursor_color_set)
|
||||
color = &priv->cursor_color;
|
||||
else
|
||||
color = &priv->text_color;
|
||||
|
||||
cogl_set_source_color4ub (color->red,
|
||||
color->green,
|
||||
color->blue,
|
||||
paint_opacity * color->alpha / 255);
|
||||
cursor_node = clutter_color_node_new (&(ClutterColor) {
|
||||
color->red,
|
||||
color->green,
|
||||
color->blue,
|
||||
paint_opacity * color->alpha / 255,
|
||||
});
|
||||
clutter_paint_node_set_name (cursor_node, "ClutterText.selection-background");
|
||||
clutter_paint_node_add_child (node, cursor_node);
|
||||
|
||||
cogl_rectangle (priv->cursor_rect.origin.x,
|
||||
priv->cursor_rect.origin.y,
|
||||
priv->cursor_rect.origin.x + priv->cursor_rect.size.width,
|
||||
priv->cursor_rect.origin.y + priv->cursor_rect.size.height);
|
||||
clutter_paint_node_add_rectangle (cursor_node,
|
||||
&(ClutterActorBox) {
|
||||
priv->cursor_rect.origin.x,
|
||||
priv->cursor_rect.origin.y,
|
||||
priv->cursor_rect.origin.x + priv->cursor_rect.size.width,
|
||||
priv->cursor_rect.origin.y + priv->cursor_rect.size.height
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Paint selection background first */
|
||||
g_autoptr(ClutterPaintNode) selection_background_node = NULL;
|
||||
g_autoptr(ClutterPaintNode) selection_text_node = NULL;
|
||||
g_autoptr(ClutterPaintNode) selection_clip_node = NULL;
|
||||
PangoLayout *layout = clutter_text_get_layout (self);
|
||||
ClutterActorBox alloc = { 0, };
|
||||
CoglPath *selection_path = cogl_path_new ();
|
||||
CoglColor cogl_color = { 0, };
|
||||
CoglFramebuffer *fb;
|
||||
|
||||
fb = cogl_get_draw_framebuffer ();
|
||||
if (G_UNLIKELY (fb == NULL))
|
||||
return;
|
||||
clutter_text_foreach_selection_rectangle (self,
|
||||
add_selection_rectangle_to_path,
|
||||
selection_path);
|
||||
|
||||
/* Clip against both the actor allocation - we don't want to draw
|
||||
* the selection rectangle outside the actor - and the selection
|
||||
* path - we don't want to render the text over the unselected
|
||||
* text either.
|
||||
*/
|
||||
selection_clip_node = clutter_clip_node_new ();
|
||||
clutter_paint_node_set_name (selection_clip_node, "ClutterText.clip-selection");
|
||||
clutter_paint_node_add_child (node, selection_clip_node);
|
||||
|
||||
clutter_actor_get_allocation_box (CLUTTER_ACTOR (self), &alloc);
|
||||
clutter_actor_box_set_origin (&alloc, 0, 0);
|
||||
|
||||
clutter_paint_node_add_rectangle (selection_clip_node, &alloc);
|
||||
clutter_paint_node_add_path (selection_clip_node, selection_path);
|
||||
|
||||
/* Paint selection background */
|
||||
if (priv->selection_color_set)
|
||||
@@ -1794,35 +1821,40 @@ selection_paint (ClutterText *self)
|
||||
else
|
||||
color = &priv->text_color;
|
||||
|
||||
cogl_set_source_color4ub (color->red,
|
||||
color->green,
|
||||
color->blue,
|
||||
paint_opacity * color->alpha / 255);
|
||||
selection_background_node = clutter_color_node_new (&(ClutterColor) {
|
||||
color->red,
|
||||
color->green,
|
||||
color->blue,
|
||||
paint_opacity * color->alpha / 255,
|
||||
});
|
||||
clutter_paint_node_set_name (selection_background_node, "ClutterText.selection-background");
|
||||
clutter_paint_node_add_child (selection_clip_node, selection_background_node);
|
||||
|
||||
clutter_text_foreach_selection_rectangle (self,
|
||||
add_selection_rectangle_to_path,
|
||||
selection_path);
|
||||
|
||||
cogl_path_fill (selection_path);
|
||||
clutter_paint_node_add_path (selection_background_node, selection_path);
|
||||
|
||||
/* Paint selected text */
|
||||
cogl_framebuffer_push_path_clip (fb, selection_path);
|
||||
cogl_object_unref (selection_path);
|
||||
|
||||
if (priv->selected_text_color_set)
|
||||
color = &priv->selected_text_color;
|
||||
else
|
||||
color = &priv->text_color;
|
||||
|
||||
cogl_color_init_from_4ub (&cogl_color,
|
||||
color->red,
|
||||
color->green,
|
||||
color->blue,
|
||||
paint_opacity * color->alpha / 255);
|
||||
selection_text_node = clutter_text_node_new (layout,
|
||||
&(ClutterColor) {
|
||||
color->red,
|
||||
color->green,
|
||||
color->blue,
|
||||
paint_opacity * color->alpha / 255,
|
||||
});
|
||||
|
||||
cogl_pango_render_layout (layout, priv->text_x, 0, &cogl_color, 0);
|
||||
clutter_paint_node_set_name (selection_text_node, "ClutterText.selection-text");
|
||||
clutter_paint_node_add_child (selection_clip_node, selection_text_node);
|
||||
|
||||
cogl_framebuffer_pop_clip (fb);
|
||||
clutter_paint_node_add_texture_rectangle (selection_text_node,
|
||||
&alloc,
|
||||
priv->text_x, priv->text_y,
|
||||
1, 1);
|
||||
|
||||
cogl_object_unref (selection_path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2373,26 +2405,43 @@ clutter_text_compute_layout_offsets (ClutterText *self,
|
||||
|
||||
#define TEXT_PADDING 2
|
||||
|
||||
static void
|
||||
clutter_text_paint (ClutterActor *self)
|
||||
static inline ClutterPaintNode *
|
||||
create_clip_node (ClutterPaintNode *node,
|
||||
float width,
|
||||
float height)
|
||||
{
|
||||
g_autoptr(ClutterPaintNode) clip_node = NULL;
|
||||
|
||||
clip_node = clutter_clip_node_new ();
|
||||
clutter_paint_node_set_name (clip_node, "ClutterText.clip");
|
||||
clutter_paint_node_add_child (node, clip_node);
|
||||
|
||||
clutter_paint_node_add_rectangle (clip_node,
|
||||
&(ClutterActorBox) {
|
||||
0, 0,
|
||||
width, height,
|
||||
});
|
||||
|
||||
return g_steal_pointer (&clip_node);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_text_paint_node (ClutterActor *self,
|
||||
ClutterPaintNode *node)
|
||||
{
|
||||
g_autoptr(ClutterPaintNode) text_node = NULL;
|
||||
ClutterText *text = CLUTTER_TEXT (self);
|
||||
ClutterTextPrivate *priv = text->priv;
|
||||
CoglFramebuffer *fb;
|
||||
PangoLayout *layout;
|
||||
ClutterActorBox alloc = { 0, };
|
||||
CoglColor color = { 0, };
|
||||
guint8 real_opacity;
|
||||
gint text_x = priv->text_x;
|
||||
gint text_y = priv->text_y;
|
||||
gboolean clip_set = FALSE;
|
||||
gboolean bg_color_set = FALSE;
|
||||
guint n_chars;
|
||||
float alloc_width;
|
||||
float alloc_height;
|
||||
|
||||
fb = cogl_get_draw_framebuffer ();
|
||||
|
||||
/* Note that if anything in this paint method changes it needs to be
|
||||
reflected in the get_paint_volume implementation which is tightly
|
||||
tied to the workings of this function */
|
||||
@@ -2405,6 +2454,7 @@ clutter_text_paint (ClutterActor *self)
|
||||
g_object_get (self, "background-color-set", &bg_color_set, NULL);
|
||||
if (bg_color_set)
|
||||
{
|
||||
g_autoptr(ClutterPaintNode) background_color_node = NULL;
|
||||
ClutterColor bg_color;
|
||||
|
||||
clutter_actor_get_background_color (self, &bg_color);
|
||||
@@ -2412,11 +2462,11 @@ clutter_text_paint (ClutterActor *self)
|
||||
* bg_color.alpha
|
||||
/ 255;
|
||||
|
||||
cogl_set_source_color4ub (bg_color.red,
|
||||
bg_color.green,
|
||||
bg_color.blue,
|
||||
bg_color.alpha);
|
||||
cogl_rectangle (0, 0, alloc_width, alloc_height);
|
||||
background_color_node = clutter_color_node_new (&bg_color);
|
||||
clutter_paint_node_set_name (background_color_node, "ClutterText.background-color");
|
||||
clutter_paint_node_add_child (node, background_color_node);
|
||||
|
||||
clutter_paint_node_add_rectangle (background_color_node, &alloc);
|
||||
}
|
||||
|
||||
/* don't bother painting an empty text actor, unless it's
|
||||
@@ -2469,8 +2519,7 @@ clutter_text_paint (ClutterActor *self)
|
||||
|
||||
pango_layout_get_extents (layout, NULL, &logical_rect);
|
||||
|
||||
cogl_framebuffer_push_rectangle_clip (fb, 0, 0, alloc_width, alloc_height);
|
||||
clip_set = TRUE;
|
||||
node = create_clip_node (node, alloc_width, alloc_height);
|
||||
|
||||
actor_width = alloc_width - 2 * TEXT_PADDING;
|
||||
text_width = logical_rect.width / PANGO_SCALE;
|
||||
@@ -2513,12 +2562,8 @@ clutter_text_paint (ClutterActor *self)
|
||||
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||||
|
||||
/* don't clip if the layout managed to fit inside our allocation */
|
||||
if (logical_rect.width > alloc_width ||
|
||||
logical_rect.height > alloc_height)
|
||||
{
|
||||
cogl_framebuffer_push_rectangle_clip (fb, 0, 0, alloc_width, alloc_height);
|
||||
clip_set = TRUE;
|
||||
}
|
||||
if (logical_rect.width > alloc_width || logical_rect.height > alloc_height)
|
||||
node = create_clip_node (node, alloc_width, alloc_height);
|
||||
|
||||
clutter_text_compute_layout_offsets (text, layout, &alloc, &text_x, &text_y);
|
||||
}
|
||||
@@ -2541,17 +2586,25 @@ clutter_text_paint (ClutterActor *self)
|
||||
CLUTTER_NOTE (PAINT, "painting text (text: '%s')",
|
||||
clutter_text_buffer_get_text (get_buffer (text)));
|
||||
|
||||
cogl_color_init_from_4ub (&color,
|
||||
priv->text_color.red,
|
||||
priv->text_color.green,
|
||||
priv->text_color.blue,
|
||||
real_opacity);
|
||||
cogl_pango_render_layout (layout, priv->text_x, priv->text_y, &color, 0);
|
||||
text_node = clutter_text_node_new (layout,
|
||||
&(ClutterColor) {
|
||||
priv->text_color.red,
|
||||
priv->text_color.green,
|
||||
priv->text_color.blue,
|
||||
real_opacity
|
||||
});
|
||||
|
||||
selection_paint (text);
|
||||
clutter_paint_node_set_name (text_node, "ClutterText.text");
|
||||
clutter_paint_node_add_child (node, text_node);
|
||||
|
||||
if (clip_set)
|
||||
cogl_framebuffer_pop_clip (fb);
|
||||
clutter_actor_box_set_origin (&alloc, 0, 0);
|
||||
clutter_paint_node_add_texture_rectangle (text_node,
|
||||
&alloc,
|
||||
priv->text_x,
|
||||
priv->text_y,
|
||||
1, 1);
|
||||
|
||||
paint_selection (text, node);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3548,7 +3601,7 @@ clutter_text_class_init (ClutterTextClass *klass)
|
||||
gobject_class->dispose = clutter_text_dispose;
|
||||
gobject_class->finalize = clutter_text_finalize;
|
||||
|
||||
actor_class->paint = clutter_text_paint;
|
||||
actor_class->paint_node = clutter_text_paint_node;
|
||||
actor_class->get_paint_volume = clutter_text_get_paint_volume;
|
||||
actor_class->get_preferred_width = clutter_text_get_preferred_width;
|
||||
actor_class->get_preferred_height = clutter_text_get_preferred_height;
|
||||
|
@@ -115,6 +115,8 @@ struct _MetaInputSettingsClass
|
||||
GDesktopStylusButtonAction tertiary);
|
||||
gboolean (* has_two_finger_scroll) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device);
|
||||
gboolean (* is_trackball_device) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device);
|
||||
};
|
||||
|
||||
GSettings * meta_input_settings_get_tablet_settings (MetaInputSettings *settings,
|
||||
@@ -141,6 +143,4 @@ WacomDevice * meta_input_settings_get_tablet_wacom_device (MetaInputSettings *se
|
||||
ClutterInputDevice *device);
|
||||
#endif
|
||||
|
||||
gboolean meta_input_device_is_trackball (ClutterInputDevice *device);
|
||||
|
||||
#endif /* META_INPUT_SETTINGS_PRIVATE_H */
|
||||
|
@@ -709,22 +709,6 @@ update_touchpad_send_events (MetaInputSettings *input_settings,
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_input_device_is_trackball (ClutterInputDevice *device)
|
||||
{
|
||||
gboolean is_trackball;
|
||||
char *name;
|
||||
|
||||
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
|
||||
return FALSE;
|
||||
|
||||
name = g_ascii_strdown (clutter_input_device_get_device_name (device), -1);
|
||||
is_trackball = strstr (name, "trackball") != NULL;
|
||||
g_free (name);
|
||||
|
||||
return is_trackball;
|
||||
}
|
||||
|
||||
static void
|
||||
update_trackball_scroll_button (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
@@ -733,11 +717,12 @@ update_trackball_scroll_button (MetaInputSettings *input_settings,
|
||||
MetaInputSettingsPrivate *priv;
|
||||
guint button;
|
||||
|
||||
if (device && !meta_input_device_is_trackball (device))
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
|
||||
if (device && !input_settings_class->is_trackball_device (input_settings, device))
|
||||
return;
|
||||
|
||||
/* This key is 'i' in the schema but it also specifies a minimum
|
||||
* range of 0 so the cast here is safe. */
|
||||
button = (guint) g_settings_get_int (priv->trackball_settings, "scroll-wheel-emulation-button");
|
||||
@@ -756,7 +741,7 @@ update_trackball_scroll_button (MetaInputSettings *input_settings,
|
||||
{
|
||||
device = devices->data;
|
||||
|
||||
if (meta_input_device_is_trackball (device))
|
||||
if (input_settings_class->is_trackball_device (input_settings, device))
|
||||
input_settings_class->set_scroll_button (input_settings, device, button);
|
||||
|
||||
devices = devices->next;
|
||||
|
@@ -398,9 +398,10 @@ is_mouse_device (ClutterInputDevice *device)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_trackball_device (ClutterInputDevice *device)
|
||||
meta_input_settings_native_is_trackball_device (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
return meta_input_device_is_trackball (device);
|
||||
return has_udev_property (device, "ID_INPUT_TRACKBALL");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -419,7 +420,7 @@ meta_input_settings_native_set_trackball_accel_profile (MetaInputSettings
|
||||
ClutterInputDevice *device,
|
||||
GDesktopPointerAccelProfile profile)
|
||||
{
|
||||
if (!is_trackball_device (device))
|
||||
if (!meta_input_settings_native_is_trackball_device (settings, device))
|
||||
return;
|
||||
|
||||
set_device_accel_profile (device, profile);
|
||||
@@ -588,6 +589,7 @@ meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass)
|
||||
input_settings_class->set_stylus_button_map = meta_input_settings_native_set_stylus_button_map;
|
||||
|
||||
input_settings_class->has_two_finger_scroll = meta_input_settings_native_has_two_finger_scroll;
|
||||
input_settings_class->is_trackball_device = meta_input_settings_native_is_trackball_device;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -500,10 +500,10 @@ is_mouse (MetaInputSettings *settings,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_trackball (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device)
|
||||
meta_input_settings_x11_is_trackball_device (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
return meta_input_device_is_trackball (device);
|
||||
return has_udev_property (settings, device, "ID_INPUT_TRACKBALL");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -566,7 +566,7 @@ meta_input_settings_x11_set_trackball_accel_profile (MetaInputSettings
|
||||
ClutterInputDevice *device,
|
||||
GDesktopPointerAccelProfile profile)
|
||||
{
|
||||
if (!is_trackball (settings, device))
|
||||
if (!meta_input_settings_x11_is_trackball_device (settings, device))
|
||||
return;
|
||||
|
||||
set_device_accel_profile (device, profile);
|
||||
@@ -782,6 +782,7 @@ meta_input_settings_x11_set_stylus_button_map (MetaInputSettings *setti
|
||||
return;
|
||||
|
||||
/* Grab the puke bucket! */
|
||||
meta_x11_error_trap_push (display->x11_display);
|
||||
xdev = device_ensure_xdevice (device);
|
||||
if (xdev)
|
||||
{
|
||||
@@ -851,6 +852,7 @@ meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass)
|
||||
input_settings_class->set_stylus_button_map = meta_input_settings_x11_set_stylus_button_map;
|
||||
|
||||
input_settings_class->has_two_finger_scroll = meta_input_settings_x11_has_two_finger_scroll;
|
||||
input_settings_class->is_trackball_device = meta_input_settings_x11_is_trackball_device;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -804,6 +804,7 @@ meta_compositor_hide_window (MetaCompositor *compositor,
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
meta_window_actor_hide (window_actor, effect);
|
||||
meta_stack_tracker_queue_sync_stack (compositor->display->stack_tracker);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -951,6 +952,9 @@ get_top_visible_window_actor (MetaCompositor *compositor)
|
||||
MetaRectangle buffer_rect;
|
||||
MetaRectangle display_rect = { 0 };
|
||||
|
||||
if (!window->visible_to_compositor)
|
||||
continue;
|
||||
|
||||
meta_window_get_buffer_rect (window, &buffer_rect);
|
||||
meta_display_get_size (compositor->display,
|
||||
&display_rect.width, &display_rect.height);
|
||||
|
@@ -52,6 +52,7 @@
|
||||
#include "meta-idle-monitor-dbus.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
#include <meta/meta-backend.h>
|
||||
#include "backends/meta-cursor-sprite-xcursor.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
|
@@ -109,6 +109,12 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
/* FIXME handle this error */
|
||||
meta_x11_error_trap_pop (x11_display);
|
||||
|
||||
/* Ensure focus is restored after the unmap/map events triggered
|
||||
* by XReparentWindow().
|
||||
*/
|
||||
if (meta_window_has_focus (window))
|
||||
window->restore_focus_on_map = TRUE;
|
||||
|
||||
/* stick frame to the window */
|
||||
window->frame = frame;
|
||||
|
||||
@@ -201,6 +207,12 @@ meta_window_destroy_frame (MetaWindow *window)
|
||||
|
||||
meta_ui_frame_unmanage (frame->ui_frame);
|
||||
|
||||
/* Ensure focus is restored after the unmap/map events triggered
|
||||
* by XReparentWindow().
|
||||
*/
|
||||
if (meta_window_has_focus (window))
|
||||
window->restore_focus_on_map = TRUE;
|
||||
|
||||
meta_x11_display_unregister_x_window (x11_display, frame->xwindow);
|
||||
|
||||
window->frame = NULL;
|
||||
|
@@ -415,6 +415,9 @@ struct _MetaWindow
|
||||
/* whether or not the window is from a program running on another machine */
|
||||
guint is_remote : 1;
|
||||
|
||||
/* whether focus should be restored on map */
|
||||
guint restore_focus_on_map : 1;
|
||||
|
||||
/* if non-NULL, the bounds of the window frame */
|
||||
cairo_region_t *frame_bounds;
|
||||
|
||||
@@ -565,6 +568,7 @@ struct _MetaWindowClass
|
||||
gboolean (*shortcuts_inhibited) (MetaWindow *window,
|
||||
ClutterInputDevice *source);
|
||||
gboolean (*is_stackable) (MetaWindow *window);
|
||||
gboolean (*are_updates_frozen) (MetaWindow *window);
|
||||
};
|
||||
|
||||
/* These differ from window->has_foo_func in that they consider
|
||||
|
@@ -3743,14 +3743,7 @@ meta_window_activate_with_workspace (MetaWindow *window,
|
||||
gboolean
|
||||
meta_window_updates_are_frozen (MetaWindow *window)
|
||||
{
|
||||
if (window->extended_sync_request_counter &&
|
||||
window->sync_request_serial % 2 == 1)
|
||||
return TRUE;
|
||||
|
||||
if (window->sync_request_serial < window->sync_request_wait_serial)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
return META_WINDOW_GET_CLASS (window)->are_updates_frozen (window);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4660,6 +4653,9 @@ meta_window_focus (MetaWindow *window,
|
||||
|
||||
g_return_if_fail (!window->override_redirect);
|
||||
|
||||
/* This is a oneshot flag */
|
||||
window->restore_focus_on_map = FALSE;
|
||||
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Setting input focus to window %s, input: %d take_focus: %d\n",
|
||||
window->desc, window->input, window->take_focus);
|
||||
@@ -7987,7 +7983,15 @@ meta_window_set_transient_for (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (window->attached && parent == NULL)
|
||||
{
|
||||
guint32 timestamp;
|
||||
|
||||
timestamp =
|
||||
meta_display_get_current_time_roundtrip (window->display);
|
||||
meta_window_unmanage (window, timestamp);
|
||||
return;
|
||||
}
|
||||
/* We know this won't create a reference cycle because we check for loops */
|
||||
g_clear_object (&window->transient_for);
|
||||
window->transient_for = parent ? g_object_ref (parent) : NULL;
|
||||
|
@@ -591,6 +591,9 @@ meta_xdg_output_manager_get_xdg_output (struct wl_client *client,
|
||||
wayland_output->xdg_output_resources =
|
||||
g_list_prepend (wayland_output->xdg_output_resources, xdg_output_resource);
|
||||
|
||||
if (!wayland_output->logical_monitor)
|
||||
return;
|
||||
|
||||
send_xdg_output_events (xdg_output_resource,
|
||||
wayland_output,
|
||||
wayland_output->logical_monitor,
|
||||
|
@@ -57,6 +57,8 @@ struct _MetaWindowWayland
|
||||
int last_sent_y;
|
||||
int last_sent_width;
|
||||
int last_sent_height;
|
||||
|
||||
gboolean has_been_shown;
|
||||
};
|
||||
|
||||
struct _MetaWindowWaylandClass
|
||||
@@ -538,6 +540,19 @@ appears_focused_changed (GObject *object,
|
||||
surface_state_changed (window);
|
||||
}
|
||||
|
||||
static void
|
||||
on_window_shown (MetaWindow *window)
|
||||
{
|
||||
MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window);
|
||||
gboolean has_been_shown;
|
||||
|
||||
has_been_shown = wl_window->has_been_shown;
|
||||
wl_window->has_been_shown = TRUE;
|
||||
|
||||
if (!has_been_shown)
|
||||
meta_compositor_sync_updates_frozen (window->display->compositor, window);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_wayland_init (MetaWindowWayland *wl_window)
|
||||
{
|
||||
@@ -547,6 +562,8 @@ meta_window_wayland_init (MetaWindowWayland *wl_window)
|
||||
|
||||
g_signal_connect (window, "notify::appears-focused",
|
||||
G_CALLBACK (appears_focused_changed), NULL);
|
||||
g_signal_connect (window, "shown",
|
||||
G_CALLBACK (on_window_shown), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -573,6 +590,14 @@ meta_window_wayland_is_stackable (MetaWindow *window)
|
||||
return meta_wayland_surface_get_buffer (window->surface) != NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_window_wayland_are_updates_frozen (MetaWindow *window)
|
||||
{
|
||||
MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window);
|
||||
|
||||
return !wl_window->has_been_shown;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_wayland_class_init (MetaWindowWaylandClass *klass)
|
||||
{
|
||||
@@ -593,6 +618,7 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass)
|
||||
window_class->force_restore_shortcuts = meta_window_wayland_force_restore_shortcuts;
|
||||
window_class->shortcuts_inhibited = meta_window_wayland_shortcuts_inhibited;
|
||||
window_class->is_stackable = meta_window_wayland_is_stackable;
|
||||
window_class->are_updates_frozen = meta_window_wayland_are_updates_frozen;
|
||||
}
|
||||
|
||||
MetaWindow *
|
||||
|
@@ -1374,6 +1374,12 @@ handle_other_xevent (MetaX11Display *x11_display,
|
||||
window = meta_window_x11_new (display, event->xmap.window,
|
||||
FALSE, META_COMP_EFFECT_CREATE);
|
||||
}
|
||||
else if (window && window->restore_focus_on_map)
|
||||
{
|
||||
meta_window_focus (window,
|
||||
meta_display_get_current_time_roundtrip (display));
|
||||
}
|
||||
|
||||
break;
|
||||
case MapRequest:
|
||||
if (window == NULL)
|
||||
|
@@ -1577,6 +1577,19 @@ meta_window_x11_is_stackable (MetaWindow *window)
|
||||
return !window->override_redirect;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_window_x11_are_updates_frozen (MetaWindow *window)
|
||||
{
|
||||
if (window->extended_sync_request_counter &&
|
||||
window->sync_request_serial % 2 == 1)
|
||||
return TRUE;
|
||||
|
||||
if (window->sync_request_serial < window->sync_request_wait_serial)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_x11_class_init (MetaWindowX11Class *klass)
|
||||
{
|
||||
@@ -1601,6 +1614,7 @@ meta_window_x11_class_init (MetaWindowX11Class *klass)
|
||||
window_class->force_restore_shortcuts = meta_window_x11_force_restore_shortcuts;
|
||||
window_class->shortcuts_inhibited = meta_window_x11_shortcuts_inhibited;
|
||||
window_class->is_stackable = meta_window_x11_is_stackable;
|
||||
window_class->are_updates_frozen = meta_window_x11_are_updates_frozen;
|
||||
}
|
||||
|
||||
void
|
||||
|
Reference in New Issue
Block a user