Compare commits
	
		
			50 Commits
		
	
	
		
			pwood/fix-
			...
			gnome-3-30
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					7a7e711b86 | ||
| 
						 | 
					fa3f227236 | ||
| 
						 | 
					5cb3b4643d | ||
| 
						 | 
					2a81dc45e7 | ||
| 
						 | 
					c05fe4ae98 | ||
| 
						 | 
					2a692a0328 | ||
| 
						 | 
					288ab54ccf | ||
| 
						 | 
					0733f22b81 | ||
| 
						 | 
					60ea32330a | ||
| 
						 | 
					03d880ad2b | ||
| 
						 | 
					bee55a27f4 | ||
| 
						 | 
					4349e682f8 | ||
| 
						 | 
					9f98743cfc | ||
| 
						 | 
					d4759df5bb | ||
| 
						 | 
					ffa4279a96 | ||
| 
						 | 
					a51188f8d7 | ||
| 
						 | 
					a9322c81af | ||
| 
						 | 
					8abd1b0092 | ||
| 
						 | 
					7d936018d2 | ||
| 
						 | 
					b1dbdd41ab | ||
| 
						 | 
					7927415e5b | ||
| 
						 | 
					2021a7206c | ||
| 
						 | 
					29ffaa6f89 | ||
| 
						 | 
					689bff0ac2 | ||
| 
						 | 
					81807fc310 | ||
| 
						 | 
					b95700dabc | ||
| 
						 | 
					d792a320be | ||
| 
						 | 
					6dbd057ef4 | ||
| 
						 | 
					49dcf50727 | ||
| 
						 | 
					ccd5e9fa08 | ||
| 
						 | 
					41d28e254a | ||
| 
						 | 
					956bb80667 | ||
| 
						 | 
					1d8c4285b9 | ||
| 
						 | 
					ffe94b0d73 | ||
| 
						 | 
					0f7c35b94a | ||
| 
						 | 
					db8a29b348 | ||
| 
						 | 
					6be3961299 | ||
| 
						 | 
					7260ba5db3 | ||
| 
						 | 
					1c57a58420 | ||
| 
						 | 
					5e4cb54bb5 | ||
| 
						 | 
					afc91f0804 | ||
| 
						 | 
					c6223ffea8 | ||
| 
						 | 
					1cb21877ed | ||
| 
						 | 
					d0de451e29 | ||
| 
						 | 
					28d2d54189 | ||
| 
						 | 
					bcd6103c44 | ||
| 
						 | 
					8eabfaaa8b | ||
| 
						 | 
					1d863f4d3e | ||
| 
						 | 
					1abab3fe2e | ||
| 
						 | 
					d364fa50ba | 
							
								
								
									
										15
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								NEWS
									
									
									
									
									
								
							@@ -1,3 +1,18 @@
 | 
			
		||||
3.30.2
 | 
			
		||||
======
 | 
			
		||||
* Fix handling of non-UTF8 encodings [Florian; !227]
 | 
			
		||||
* Fix memory leaks introduced in 3.30.1 [Jonas; #653]
 | 
			
		||||
* Work around hangul text input bug [Carlos; gtk#1365]
 | 
			
		||||
* Fix crash when restarting window manager [Andrea; gnome-shell#595]
 | 
			
		||||
* Fix crash on monitor hotplug [Olivier; #189]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Jonas Ådahl, Andrea Azzarone, Olivier Fourdan, Carlos Garnacho,
 | 
			
		||||
  Florian Müllner, Akira Nakajima
 | 
			
		||||
 | 
			
		||||
Translators:
 | 
			
		||||
  Dušan Kazik [sk]
 | 
			
		||||
 | 
			
		||||
3.30.1
 | 
			
		||||
======
 | 
			
		||||
* Improve trackball detection [Tony; #258]
 | 
			
		||||
 
 | 
			
		||||
@@ -186,6 +186,12 @@ update_fbo (ClutterEffect *effect, int fbo_width, int fbo_height)
 | 
			
		||||
      priv->texture = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->offscreen != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      cogl_handle_unref (priv->offscreen);
 | 
			
		||||
      priv->offscreen = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  priv->texture =
 | 
			
		||||
    clutter_offscreen_effect_create_texture (self, fbo_width, fbo_height);
 | 
			
		||||
  if (priv->texture == NULL)
 | 
			
		||||
@@ -196,9 +202,6 @@ update_fbo (ClutterEffect *effect, int fbo_width, int fbo_height)
 | 
			
		||||
  priv->fbo_width = fbo_width;
 | 
			
		||||
  priv->fbo_height = fbo_height;
 | 
			
		||||
 | 
			
		||||
  if (priv->offscreen != NULL)
 | 
			
		||||
    cogl_handle_unref (priv->offscreen);
 | 
			
		||||
 | 
			
		||||
  priv->offscreen = cogl_offscreen_new_to_texture (priv->texture);
 | 
			
		||||
  if (priv->offscreen == NULL)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -1166,6 +1166,21 @@ _clutter_paint_volume_get_stage_paint_box (ClutterPaintVolume *pv,
 | 
			
		||||
 | 
			
		||||
  _clutter_paint_volume_get_bounding_box (&projected_pv, box);
 | 
			
		||||
 | 
			
		||||
  if (pv->is_2d && pv->actor &&
 | 
			
		||||
      clutter_actor_get_z_position (pv->actor) == 0)
 | 
			
		||||
    {
 | 
			
		||||
      /* If the volume/actor are perfectly 2D, take the bounding box as
 | 
			
		||||
       * good. We won't need to add any extra room for sub-pixel positioning
 | 
			
		||||
       * in this case.
 | 
			
		||||
       */
 | 
			
		||||
      clutter_paint_volume_free (&projected_pv);
 | 
			
		||||
      box->x1 = CLUTTER_NEARBYINT (box->x1);
 | 
			
		||||
      box->y1 = CLUTTER_NEARBYINT (box->y1);
 | 
			
		||||
      box->x2 = CLUTTER_NEARBYINT (box->x2);
 | 
			
		||||
      box->y2 = CLUTTER_NEARBYINT (box->y2);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* The aim here is that for a given rectangle defined with floating point
 | 
			
		||||
   * coordinates we want to determine a stable quantized size in pixels
 | 
			
		||||
   * that doesn't vary due to the original box's sub-pixel position.
 | 
			
		||||
 
 | 
			
		||||
@@ -677,7 +677,7 @@ stop_toggle_slowkeys (ClutterInputDeviceEvdev *device)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_togglekeys_press (ClutterEvent            *event,
 | 
			
		||||
handle_enablekeys_press (ClutterEvent            *event,
 | 
			
		||||
                         ClutterInputDeviceEvdev *device)
 | 
			
		||||
{
 | 
			
		||||
  if (event->key.keyval == XKB_KEY_Shift_L || event->key.keyval == XKB_KEY_Shift_R)
 | 
			
		||||
@@ -699,7 +699,7 @@ handle_togglekeys_press (ClutterEvent            *event,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_togglekeys_release (ClutterEvent            *event,
 | 
			
		||||
handle_enablekeys_release (ClutterEvent            *event,
 | 
			
		||||
                           ClutterInputDeviceEvdev *device)
 | 
			
		||||
{
 | 
			
		||||
  if (event->key.keyval == XKB_KEY_Shift_L || event->key.keyval == XKB_KEY_Shift_R)
 | 
			
		||||
@@ -1133,9 +1133,14 @@ clutter_input_device_evdev_process_kbd_a11y_event (ClutterEvent               *e
 | 
			
		||||
  if (event->key.flags & CLUTTER_EVENT_FLAG_INPUT_METHOD)
 | 
			
		||||
    goto emit_event;
 | 
			
		||||
 | 
			
		||||
  if (!device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED)
 | 
			
		||||
  if (!(device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED))
 | 
			
		||||
    goto emit_event;
 | 
			
		||||
 | 
			
		||||
  if (event->type == CLUTTER_KEY_PRESS)
 | 
			
		||||
    handle_enablekeys_press (event, device_evdev);
 | 
			
		||||
  else
 | 
			
		||||
    handle_enablekeys_release (event, device_evdev);
 | 
			
		||||
 | 
			
		||||
  if (device_evdev->a11y_flags & CLUTTER_A11Y_MOUSE_KEYS_ENABLED)
 | 
			
		||||
    {
 | 
			
		||||
      if (event->type == CLUTTER_KEY_PRESS &&
 | 
			
		||||
@@ -1146,14 +1151,6 @@ clutter_input_device_evdev_process_kbd_a11y_event (ClutterEvent               *e
 | 
			
		||||
        return; /* swallow event */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (device_evdev->a11y_flags & CLUTTER_A11Y_TOGGLE_KEYS_ENABLED)
 | 
			
		||||
    {
 | 
			
		||||
      if (event->type == CLUTTER_KEY_PRESS)
 | 
			
		||||
        handle_togglekeys_press (event, device_evdev);
 | 
			
		||||
      else
 | 
			
		||||
        handle_togglekeys_release (event, device_evdev);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if ((device_evdev->a11y_flags & CLUTTER_A11Y_BOUNCE_KEYS_ENABLED) &&
 | 
			
		||||
      (get_debounce_delay (device) != 0))
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -79,6 +79,9 @@ struct _ClutterKeymapX11
 | 
			
		||||
  guint current_cache_serial;
 | 
			
		||||
  DirectionCacheEntry group_direction_cache[4];
 | 
			
		||||
  int current_group;
 | 
			
		||||
 | 
			
		||||
  GHashTable *reserved_keycodes;
 | 
			
		||||
  GQueue *available_keycodes;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  guint caps_lock_state : 1;
 | 
			
		||||
@@ -441,16 +444,100 @@ clutter_keymap_x11_set_property (GObject      *gobject,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_XKB
 | 
			
		||||
static void
 | 
			
		||||
clutter_keymap_x11_refresh_reserved_keycodes (ClutterKeymapX11 *keymap_x11)
 | 
			
		||||
{
 | 
			
		||||
  Display *dpy = clutter_x11_get_default_display ();
 | 
			
		||||
  GHashTableIter iter;
 | 
			
		||||
  gpointer key, value;
 | 
			
		||||
 | 
			
		||||
  g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes);
 | 
			
		||||
  while (g_hash_table_iter_next (&iter, &key, &value))
 | 
			
		||||
    {
 | 
			
		||||
      guint reserved_keycode = GPOINTER_TO_UINT (key);
 | 
			
		||||
      guint reserved_keysym = GPOINTER_TO_UINT (value);
 | 
			
		||||
      guint actual_keysym = XkbKeycodeToKeysym (dpy, reserved_keycode, 0, 0);
 | 
			
		||||
 | 
			
		||||
      /* If an available keycode is no longer mapped to the stored keysym, then
 | 
			
		||||
       * the keycode should not be considered available anymore and should be
 | 
			
		||||
       * removed both from the list of available and reserved keycodes.
 | 
			
		||||
       */
 | 
			
		||||
      if (reserved_keysym != actual_keysym)
 | 
			
		||||
        {
 | 
			
		||||
          g_hash_table_iter_remove (&iter);
 | 
			
		||||
          g_queue_remove (keymap_x11->available_keycodes, key);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
clutter_keymap_x11_replace_keycode (ClutterKeymapX11 *keymap_x11,
 | 
			
		||||
                                    KeyCode           keycode,
 | 
			
		||||
                                    KeySym            keysym)
 | 
			
		||||
{
 | 
			
		||||
  if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb)
 | 
			
		||||
    {
 | 
			
		||||
      Display *dpy = clutter_x11_get_default_display ();
 | 
			
		||||
      XkbDescPtr xkb = get_xkb (keymap_x11);
 | 
			
		||||
      XkbMapChangesRec changes;
 | 
			
		||||
 | 
			
		||||
      XFlush (dpy);
 | 
			
		||||
 | 
			
		||||
      xkb->device_spec = XkbUseCoreKbd;
 | 
			
		||||
      memset (&changes, 0, sizeof(changes));
 | 
			
		||||
 | 
			
		||||
      if (keysym != NoSymbol)
 | 
			
		||||
        {
 | 
			
		||||
          int types[XkbNumKbdGroups] = { XkbOneLevelIndex };
 | 
			
		||||
          XkbChangeTypesOfKey (xkb, keycode, 1, XkbGroup1Mask, types, &changes);
 | 
			
		||||
          XkbKeySymEntry (xkb, keycode, 0, 0) = keysym;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          /* Reset to NoSymbol */
 | 
			
		||||
          XkbChangeTypesOfKey (xkb, keycode, 0, XkbGroup1Mask, NULL, &changes);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      changes.changed = XkbKeySymsMask | XkbKeyTypesMask;
 | 
			
		||||
      changes.first_key_sym = keycode;
 | 
			
		||||
      changes.num_key_syms = 1;
 | 
			
		||||
      changes.first_type = 0;
 | 
			
		||||
      changes.num_types = xkb->map->num_types;
 | 
			
		||||
      XkbChangeMap (dpy, xkb, &changes);
 | 
			
		||||
 | 
			
		||||
      XFlush (dpy);
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_keymap_x11_finalize (GObject *gobject)
 | 
			
		||||
{
 | 
			
		||||
  ClutterKeymapX11 *keymap;
 | 
			
		||||
  ClutterEventTranslator *translator;
 | 
			
		||||
  GHashTableIter iter;
 | 
			
		||||
  gpointer key, value;
 | 
			
		||||
 | 
			
		||||
  keymap = CLUTTER_KEYMAP_X11 (gobject);
 | 
			
		||||
  translator = CLUTTER_EVENT_TRANSLATOR (keymap);
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_XKB
 | 
			
		||||
  clutter_keymap_x11_refresh_reserved_keycodes (keymap);
 | 
			
		||||
  g_hash_table_iter_init (&iter, keymap->reserved_keycodes);
 | 
			
		||||
  while (g_hash_table_iter_next (&iter, &key, &value))
 | 
			
		||||
    {
 | 
			
		||||
      guint keycode = GPOINTER_TO_UINT (key);
 | 
			
		||||
      clutter_keymap_x11_replace_keycode (keymap, keycode, NoSymbol);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_hash_table_destroy (keymap->reserved_keycodes);
 | 
			
		||||
  g_queue_free (keymap->available_keycodes);
 | 
			
		||||
 | 
			
		||||
  _clutter_backend_remove_event_translator (keymap->backend, translator);
 | 
			
		||||
 | 
			
		||||
  if (keymap->xkb_desc != NULL)
 | 
			
		||||
@@ -460,6 +547,7 @@ clutter_keymap_x11_finalize (GObject *gobject)
 | 
			
		||||
  G_OBJECT_CLASS (clutter_keymap_x11_parent_class)->finalize (gobject);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_keymap_x11_class_init (ClutterKeymapX11Class *klass)
 | 
			
		||||
{
 | 
			
		||||
@@ -483,6 +571,11 @@ clutter_keymap_x11_init (ClutterKeymapX11 *keymap)
 | 
			
		||||
{
 | 
			
		||||
  keymap->current_direction = PANGO_DIRECTION_NEUTRAL;
 | 
			
		||||
  keymap->current_group = -1;
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_XKB
 | 
			
		||||
  keymap->reserved_keycodes = g_hash_table_new (NULL, NULL);
 | 
			
		||||
  keymap->available_keycodes = g_queue_new ();
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ClutterTranslateReturn
 | 
			
		||||
@@ -766,6 +859,80 @@ clutter_keymap_x11_get_entries_for_keyval (ClutterKeymapX11  *keymap_x11,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_XKB
 | 
			
		||||
static guint
 | 
			
		||||
clutter_keymap_x11_get_available_keycode (ClutterKeymapX11 *keymap_x11)
 | 
			
		||||
{
 | 
			
		||||
  if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_keymap_x11_refresh_reserved_keycodes (keymap_x11);
 | 
			
		||||
 | 
			
		||||
      if (g_hash_table_size (keymap_x11->reserved_keycodes) < 5)
 | 
			
		||||
        {
 | 
			
		||||
          Display *dpy = clutter_x11_get_default_display ();
 | 
			
		||||
          XkbDescPtr xkb = get_xkb (keymap_x11);
 | 
			
		||||
          guint i;
 | 
			
		||||
 | 
			
		||||
          for (i = xkb->max_key_code; i >= xkb->min_key_code; --i)
 | 
			
		||||
            {
 | 
			
		||||
              if (XkbKeycodeToKeysym (dpy, i, 0, 0) == NoSymbol)
 | 
			
		||||
                return i;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      return GPOINTER_TO_UINT (g_queue_pop_head (keymap_x11->available_keycodes));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
gboolean clutter_keymap_x11_reserve_keycode (ClutterKeymapX11 *keymap_x11,
 | 
			
		||||
                                             guint             keyval,
 | 
			
		||||
                                             guint            *keycode_out)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap_x11), FALSE);
 | 
			
		||||
  g_return_val_if_fail (keyval != 0, FALSE);
 | 
			
		||||
  g_return_val_if_fail (keycode_out != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_XKB
 | 
			
		||||
  *keycode_out = clutter_keymap_x11_get_available_keycode (keymap_x11);
 | 
			
		||||
 | 
			
		||||
  if (*keycode_out == NoSymbol)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Cannot reserve a keycode for keyval %d: no available keycode", keyval);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!clutter_keymap_x11_replace_keycode (keymap_x11, *keycode_out, keyval))
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Failed to remap keycode %d to keyval %d", *keycode_out, keyval);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_hash_table_insert (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (*keycode_out), GUINT_TO_POINTER (keyval));
 | 
			
		||||
  g_queue_remove (keymap_x11->available_keycodes, GUINT_TO_POINTER (*keycode_out));
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
#else
 | 
			
		||||
  return FALSE;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void clutter_keymap_x11_release_keycode_if_needed (ClutterKeymapX11 *keymap_x11,
 | 
			
		||||
                                                   guint             keycode)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap_x11));
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_XKB
 | 
			
		||||
  if (!g_hash_table_contains (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (keycode)) ||
 | 
			
		||||
      g_queue_index (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)) != -1)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  g_queue_push_tail (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode));
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11,
 | 
			
		||||
                                    uint32_t          level,
 | 
			
		||||
@@ -838,6 +1005,26 @@ clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!found)
 | 
			
		||||
    {
 | 
			
		||||
      GHashTableIter iter;
 | 
			
		||||
      gpointer key, value;
 | 
			
		||||
 | 
			
		||||
      g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes);
 | 
			
		||||
      while (!found && g_hash_table_iter_next (&iter, &key, &value))
 | 
			
		||||
        {
 | 
			
		||||
          guint reserved_keycode = GPOINTER_TO_UINT (key);
 | 
			
		||||
          guint reserved_keysym = GPOINTER_TO_UINT (value);
 | 
			
		||||
 | 
			
		||||
          if (keyval == reserved_keysym)
 | 
			
		||||
            {
 | 
			
		||||
              *keycode_out = reserved_keycode;
 | 
			
		||||
              *level_out = 0;
 | 
			
		||||
              found = TRUE;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_free (keys);
 | 
			
		||||
  return found;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -58,7 +58,11 @@ gboolean clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11,
 | 
			
		||||
void     clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11,
 | 
			
		||||
                                             uint32_t          level,
 | 
			
		||||
                                             gboolean          enable);
 | 
			
		||||
 | 
			
		||||
gboolean clutter_keymap_x11_reserve_keycode (ClutterKeymapX11 *keymap_x11,
 | 
			
		||||
                                             guint             keyval,
 | 
			
		||||
                                             guint            *keycode_out);
 | 
			
		||||
void     clutter_keymap_x11_release_keycode_if_needed (ClutterKeymapX11 *keymap_x11,
 | 
			
		||||
                                                       guint             keycode);
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __CLUTTER_KEYMAP_X11_H__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -143,8 +143,13 @@ clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtu
 | 
			
		||||
 | 
			
		||||
  if (!clutter_keymap_x11_keycode_for_keyval (keymap, keyval, &keycode, &level))
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("No keycode found for keyval %x in current group", keyval);
 | 
			
		||||
      return;
 | 
			
		||||
      level = 0;
 | 
			
		||||
 | 
			
		||||
      if (!clutter_keymap_x11_reserve_keycode (keymap, keyval, &keycode))
 | 
			
		||||
        {
 | 
			
		||||
          g_warning ("No keycode found for keyval %x in current group", keyval);
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode) &&
 | 
			
		||||
@@ -155,9 +160,13 @@ clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtu
 | 
			
		||||
                     (KeyCode) keycode,
 | 
			
		||||
                     key_state == CLUTTER_KEY_STATE_PRESSED, 0);
 | 
			
		||||
 | 
			
		||||
  if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode) &&
 | 
			
		||||
      key_state == CLUTTER_KEY_STATE_RELEASED)
 | 
			
		||||
    clutter_keymap_x11_latch_modifiers (keymap, level, FALSE);
 | 
			
		||||
 | 
			
		||||
  if (key_state == CLUTTER_KEY_STATE_RELEASED)
 | 
			
		||||
    {
 | 
			
		||||
      if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode))
 | 
			
		||||
        clutter_keymap_x11_latch_modifiers (keymap, level, FALSE);
 | 
			
		||||
      clutter_keymap_x11_release_keycode_if_needed (keymap, keycode);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
@@ -230,13 +230,13 @@ paint_cb (ClutterStage *stage,
 | 
			
		||||
  gboolean *was_painted = data;
 | 
			
		||||
 | 
			
		||||
  /* old shader effect */
 | 
			
		||||
  g_assert_cmpint (get_pixel (50, 50), ==, 0xff0000);
 | 
			
		||||
  g_assert_cmpint (get_pixel (0, 25), ==, 0xff0000);
 | 
			
		||||
  /* new shader effect */
 | 
			
		||||
  g_assert_cmpint (get_pixel (150, 50), ==, 0x00ffff);
 | 
			
		||||
  g_assert_cmpint (get_pixel (100, 25), ==, 0x00ffff);
 | 
			
		||||
  /* another new shader effect */
 | 
			
		||||
  g_assert_cmpint (get_pixel (250, 50), ==, 0xff00ff);
 | 
			
		||||
  g_assert_cmpint (get_pixel (200, 25), ==, 0xff00ff);
 | 
			
		||||
  /* new shader effect */
 | 
			
		||||
  g_assert_cmpint (get_pixel (350, 50), ==, 0x00ffff);
 | 
			
		||||
  g_assert_cmpint (get_pixel (300, 25), ==, 0x00ffff);
 | 
			
		||||
 | 
			
		||||
  *was_painted = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -492,9 +492,6 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
 | 
			
		||||
      _cogl_bitmask_destroy (&uniforms_state->changed_mask);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
 | 
			
		||||
    g_slice_free (CoglPipelineBigState, pipeline->big_state);
 | 
			
		||||
 | 
			
		||||
  if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS)
 | 
			
		||||
    {
 | 
			
		||||
      g_list_foreach (pipeline->layer_differences,
 | 
			
		||||
@@ -508,6 +505,9 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
 | 
			
		||||
  if (pipeline->differences & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS)
 | 
			
		||||
    _cogl_pipeline_snippet_list_free (&pipeline->big_state->fragment_snippets);
 | 
			
		||||
 | 
			
		||||
  if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
 | 
			
		||||
    g_slice_free (CoglPipelineBigState, pipeline->big_state);
 | 
			
		||||
 | 
			
		||||
  g_list_free (pipeline->deprecated_get_layers_list);
 | 
			
		||||
 | 
			
		||||
  recursively_free_layer_caches (pipeline);
 | 
			
		||||
 
 | 
			
		||||
@@ -94,6 +94,7 @@ cogl_texture_new_with_size (unsigned int width,
 | 
			
		||||
      if (!cogl_texture_allocate (tex, &skip_error))
 | 
			
		||||
        {
 | 
			
		||||
          cogl_error_free (skip_error);
 | 
			
		||||
          skip_error = NULL;
 | 
			
		||||
          cogl_object_unref (tex);
 | 
			
		||||
          tex = NULL;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ AC_PREREQ(2.62)
 | 
			
		||||
 | 
			
		||||
m4_define([mutter_major_version], [3])
 | 
			
		||||
m4_define([mutter_minor_version], [30])
 | 
			
		||||
m4_define([mutter_micro_version], [1])
 | 
			
		||||
m4_define([mutter_micro_version], [2])
 | 
			
		||||
 | 
			
		||||
m4_define([mutter_version],
 | 
			
		||||
          [mutter_major_version.mutter_minor_version.mutter_micro_version])
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								po/de.po
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								po/de.po
									
									
									
									
									
								
							@@ -13,9 +13,9 @@ msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: mutter master\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2018-07-07 09:58+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2018-08-04 19:59+0200\n"
 | 
			
		||||
"Last-Translator: Mario Blättermann <mario.blaettermann@gmail.com>\n"
 | 
			
		||||
"POT-Creation-Date: 2019-08-06 00:49+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2019-09-05 23:42+0200\n"
 | 
			
		||||
"Last-Translator: Christian Kirbach <christian.kirbach@gmail.com>\n"
 | 
			
		||||
"Language-Team: Deutsch <gnome-de@gnome.org>\n"
 | 
			
		||||
"Language: de\n"
 | 
			
		||||
"MIME-Version: 1.0\n"
 | 
			
		||||
@@ -152,13 +152,15 @@ msgstr "Zur Arbeitsfläche 4 wechseln"
 | 
			
		||||
msgid "Switch to last workspace"
 | 
			
		||||
msgstr "Zur letzten Arbeitsfläche wechseln"
 | 
			
		||||
 | 
			
		||||
# Wechsel der Arbeitsfläche. Es wird nichts verschoben.
 | 
			
		||||
#: data/50-mutter-navigation.xml:123
 | 
			
		||||
msgid "Move to workspace above"
 | 
			
		||||
msgstr "Auf Arbeitsfläche darüber verschieben"
 | 
			
		||||
msgstr "Zur Arbeitsfläche darüber wechseln"
 | 
			
		||||
 | 
			
		||||
# Wechsel der Arbeitsfläche. Es wird nichts verschoben.
 | 
			
		||||
#: data/50-mutter-navigation.xml:126
 | 
			
		||||
msgid "Move to workspace below"
 | 
			
		||||
msgstr "Auf Arbeitsfläche darunter verschieben"
 | 
			
		||||
msgstr "Zur Arbeitsfläche darunter wechseln"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6
 | 
			
		||||
msgid "System"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										53
									
								
								po/es.po
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								po/es.po
									
									
									
									
									
								
							@@ -7,14 +7,14 @@
 | 
			
		||||
# Pablo Gonzalo del Campo <pablodc@bigfoot.com>,2002,2003.
 | 
			
		||||
# Francisco Javier F. Serrador <serrador@cvs.gnome.org>, 2004, 2005, 2006.
 | 
			
		||||
# Jorge González <jorgegonz@svn.gnome.org>, 2007, 2008, 2009, 2010, 2011.
 | 
			
		||||
# Daniel Mustieles <daniel.mustieles@gmail.com>, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018.
 | 
			
		||||
# Daniel Mustieles <daniel.mustieles@gmail.com>, 2011-2019.
 | 
			
		||||
#
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: mutter.master\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2018-07-07 09:58+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2018-07-23 12:31+0200\n"
 | 
			
		||||
"POT-Creation-Date: 2019-06-13 16:46+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2019-06-20 09:25+0200\n"
 | 
			
		||||
"Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
 | 
			
		||||
"Language-Team: es <gnome-es-list@gnome.org>\n"
 | 
			
		||||
"Language: es\n"
 | 
			
		||||
@@ -22,7 +22,7 @@ msgstr ""
 | 
			
		||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
			
		||||
"Content-Transfer-Encoding: 8bit\n"
 | 
			
		||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 | 
			
		||||
"X-Generator: Gtranslator 2.91.6\n"
 | 
			
		||||
"X-Generator: Gtranslator 3.32.0\n"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:6
 | 
			
		||||
msgid "Navigation"
 | 
			
		||||
@@ -397,7 +397,6 @@ msgid "Enable experimental features"
 | 
			
		||||
msgstr "Activar las características experimentales"
 | 
			
		||||
 | 
			
		||||
#: data/org.gnome.mutter.gschema.xml.in:108
 | 
			
		||||
#, fuzzy
 | 
			
		||||
#| msgid ""
 | 
			
		||||
#| "To enable experimental features, add the feature keyword to the list. "
 | 
			
		||||
#| "Whether the feature requires restarting the compositor depends on the "
 | 
			
		||||
@@ -429,9 +428,7 @@ msgstr ""
 | 
			
		||||
"manera predeterminada de disponer monitores lógicos en un espacio lógico de "
 | 
			
		||||
"coordenadas de píxeles, al escalar framebuffers de monitores framebuffers en "
 | 
			
		||||
"lugar del contenido de ventana, para administrar monitores HiDPI. No "
 | 
			
		||||
"requiere un reinicio. • \"remote-desktop\" — activa el escritorio remoto. "
 | 
			
		||||
"Para soportarlo con compartición de pantalla es necesario activar \"screen-"
 | 
			
		||||
"cast\" • \"screen-cast\" — activa el soporte de compartición de pantalla."
 | 
			
		||||
"requiere un reinicio."
 | 
			
		||||
 | 
			
		||||
#: data/org.gnome.mutter.gschema.xml.in:141
 | 
			
		||||
msgid "Select window from tab popup"
 | 
			
		||||
@@ -513,6 +510,11 @@ msgid ""
 | 
			
		||||
"window or be among the applications white-listed in key “xwayland-grab-"
 | 
			
		||||
"access-rules”."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Permitir que las pulsaciones del teclado emitidas por aplicaciones X11 "
 | 
			
		||||
"ejecutándose en XWayland se tengan en cuenta. Para que una pulsación X11 se "
 | 
			
		||||
"tenga en cuenta en Wayland el cliente debe o bien enviar un ClientMessage "
 | 
			
		||||
"específico de X11 a la ventana raíz o estar en la lista blanca de "
 | 
			
		||||
"aplicaciones en la clave “xwayland-grab-access-rules”."
 | 
			
		||||
 | 
			
		||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:77
 | 
			
		||||
msgid "Xwayland applications allowed to issue keyboard grabs"
 | 
			
		||||
@@ -531,11 +533,20 @@ msgid ""
 | 
			
		||||
"using the specific keyboard shortcut defined by the keybinding key “restore-"
 | 
			
		||||
"shortcuts”."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Lista los nombres o las clases de recursos de ventanas X11 permitidas o no "
 | 
			
		||||
"para emitir pulsaciones de teclado X11 en XWayland. El nombre o la clase del "
 | 
			
		||||
"recurso de una ventana X11 dada se puede obtener usando el comando “xprop "
 | 
			
		||||
"WM_CLASS”. Se soportan los comodines «*» y «?». Los valores que empiecen por "
 | 
			
		||||
"«!» están en lista negra, que tiene prioridad sobre la lista blanca, para "
 | 
			
		||||
"revocar aplicaciones de la lista predeterminada del sistema. Esta lista "
 | 
			
		||||
"incluye las siguientes aplicaciones: “@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@”. "
 | 
			
		||||
"Los usuarios pueden romper una pulsación existente usando el atajo "
 | 
			
		||||
"específico del teclado definido por la clave “restore-shortcuts”."
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: This string refers to a button that switches between
 | 
			
		||||
#. * different modes.
 | 
			
		||||
#.
 | 
			
		||||
#: src/backends/meta-input-settings.c:2325
 | 
			
		||||
#: src/backends/meta-input-settings.c:2310
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Mode Switch (Group %d)"
 | 
			
		||||
msgstr "Cambiar modo (grupo %d)"
 | 
			
		||||
@@ -543,37 +554,37 @@ msgstr "Cambiar modo (grupo %d)"
 | 
			
		||||
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
 | 
			
		||||
#. * mapping through the available outputs.
 | 
			
		||||
#.
 | 
			
		||||
#: src/backends/meta-input-settings.c:2348
 | 
			
		||||
#: src/backends/meta-input-settings.c:2333
 | 
			
		||||
msgid "Switch monitor"
 | 
			
		||||
msgstr "Cambiar monitor"
 | 
			
		||||
 | 
			
		||||
#: src/backends/meta-input-settings.c:2350
 | 
			
		||||
#: src/backends/meta-input-settings.c:2335
 | 
			
		||||
msgid "Show on-screen help"
 | 
			
		||||
msgstr "Mostrar la ayuda en pantalla"
 | 
			
		||||
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:907
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:886
 | 
			
		||||
msgid "Built-in display"
 | 
			
		||||
msgstr "Pantalla integrada"
 | 
			
		||||
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:930
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:909
 | 
			
		||||
msgid "Unknown"
 | 
			
		||||
msgstr "Desconocida"
 | 
			
		||||
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:932
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:911
 | 
			
		||||
msgid "Unknown Display"
 | 
			
		||||
msgstr "Pantalla desconocida"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
 | 
			
		||||
#. * size in inches, like 'Dell 15"'
 | 
			
		||||
#.
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:940
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:919
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s %s"
 | 
			
		||||
msgstr "%s %s"
 | 
			
		||||
 | 
			
		||||
#. This probably means that a non-WM compositor like xcompmgr is running;
 | 
			
		||||
#. * we have no way to get it to exit
 | 
			
		||||
#: src/compositor/compositor.c:481
 | 
			
		||||
#: src/compositor/compositor.c:507
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"Another compositing manager is already running on screen %i on display “%s”."
 | 
			
		||||
@@ -679,7 +690,7 @@ msgstr "Imprimir versión"
 | 
			
		||||
msgid "Mutter plugin to use"
 | 
			
		||||
msgstr "Complemento de mutter que usar"
 | 
			
		||||
 | 
			
		||||
#: src/core/prefs.c:1915
 | 
			
		||||
#: src/core/prefs.c:1787
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Workspace %d"
 | 
			
		||||
msgstr "Área de trabajo %d"
 | 
			
		||||
@@ -693,7 +704,7 @@ msgstr "Mutter fue compilado sin soporte para modo prolijo\n"
 | 
			
		||||
msgid "Mode Switch: Mode %d"
 | 
			
		||||
msgstr "Cambiar modo: modo %d"
 | 
			
		||||
 | 
			
		||||
#: src/x11/meta-x11-display.c:666
 | 
			
		||||
#: src/x11/meta-x11-display.c:672
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"Display “%s” already has a window manager; try using the --replace option to "
 | 
			
		||||
@@ -702,16 +713,16 @@ msgstr ""
 | 
			
		||||
"La pantalla «%s» ya tiene un gestor de ventanas; pruebe a usar la opción «--"
 | 
			
		||||
"replace» para reemplazar el gestor de ventanas activo."
 | 
			
		||||
 | 
			
		||||
#: src/x11/meta-x11-display.c:1010
 | 
			
		||||
#: src/x11/meta-x11-display.c:1016
 | 
			
		||||
msgid "Failed to initialize GDK\n"
 | 
			
		||||
msgstr "Falló al inicializar GDK\n"
 | 
			
		||||
 | 
			
		||||
#: src/x11/meta-x11-display.c:1034
 | 
			
		||||
#: src/x11/meta-x11-display.c:1040
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Failed to open X Window System display “%s”\n"
 | 
			
		||||
msgstr "Ocurrió un error al abrir la pantalla de X Window System «%s»\n"
 | 
			
		||||
 | 
			
		||||
#: src/x11/meta-x11-display.c:1117
 | 
			
		||||
#: src/x11/meta-x11-display.c:1123
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Screen %d on display “%s” is invalid\n"
 | 
			
		||||
msgstr "La ventana %d en la pantalla «%s» no es válida\n"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										282
									
								
								po/eu.po
									
									
									
									
									
								
							
							
						
						
									
										282
									
								
								po/eu.po
									
									
									
									
									
								
							@@ -4,21 +4,20 @@
 | 
			
		||||
#
 | 
			
		||||
# Hizkuntza Politikarako Sailburuordetza <hizpol@ej-gv.es>, 2004.
 | 
			
		||||
# Iñaki Larrañaga Murgoitio <dooteo@zundan.com>, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011.
 | 
			
		||||
# Iñaki Larrañaga Murgoitio <dooteo@zundan.com>, 2012, 2013, 2014, 2015, 2016, 2017.
 | 
			
		||||
# Iñaki Larrañaga Murgoitio <dooteo@zundan.com>, 2012, 2013, 2014, 2015, 2016, 2017, 2018.
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: mutter master\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?"
 | 
			
		||||
"product=mutter&keywords=I18N+L10N&component=general\n"
 | 
			
		||||
"POT-Creation-Date: 2017-08-21 04:46+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2017-08-27 16:47+0200\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2018-10-22 16:18+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2018-12-06 13:05+0100\n"
 | 
			
		||||
"Last-Translator: Iñaki Larrañaga Murgoitio <dooteo@zundan.com>\n"
 | 
			
		||||
"Language-Team: Basque <librezale@librezale.eus>\n"
 | 
			
		||||
"Language: eu\n"
 | 
			
		||||
"MIME-Version: 1.0\n"
 | 
			
		||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
			
		||||
"Content-Transfer-Encoding: 8bit\n"
 | 
			
		||||
"X-Generator: Lokalize 1.5\n"
 | 
			
		||||
"X-Generator: Lokalize 2.0\n"
 | 
			
		||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:6
 | 
			
		||||
@@ -46,134 +45,118 @@ msgid "Move window to last workspace"
 | 
			
		||||
msgstr "Eraman leihoa azkeneko laneko areara"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:24
 | 
			
		||||
msgid "Move window one workspace to the left"
 | 
			
		||||
msgstr "Eraman leihoa laneko area bat ezkerrera"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:27
 | 
			
		||||
msgid "Move window one workspace to the right"
 | 
			
		||||
msgstr "Eraman leihoa laneko area bat eskuinera"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:30
 | 
			
		||||
msgid "Move window one workspace up"
 | 
			
		||||
msgstr "Eraman leihoa laneko area bat gora"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:33
 | 
			
		||||
#: data/50-mutter-navigation.xml:27
 | 
			
		||||
msgid "Move window one workspace down"
 | 
			
		||||
msgstr "Eraman leihoa laneko area bat behera"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:36
 | 
			
		||||
#: data/50-mutter-navigation.xml:30
 | 
			
		||||
msgid "Move window one monitor to the left"
 | 
			
		||||
msgstr "Eraman leihoa monitore bat ezkerrera"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:39
 | 
			
		||||
#: data/50-mutter-navigation.xml:33
 | 
			
		||||
msgid "Move window one monitor to the right"
 | 
			
		||||
msgstr "Eraman leihoa monitore bat eskuinera"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:42
 | 
			
		||||
#: data/50-mutter-navigation.xml:36
 | 
			
		||||
msgid "Move window one monitor up"
 | 
			
		||||
msgstr "Eraman leihoa monitore bat gora"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:45
 | 
			
		||||
#: data/50-mutter-navigation.xml:39
 | 
			
		||||
msgid "Move window one monitor down"
 | 
			
		||||
msgstr "Eraman leihoa monitore bat behera"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:49
 | 
			
		||||
#: data/50-mutter-navigation.xml:43
 | 
			
		||||
msgid "Switch applications"
 | 
			
		||||
msgstr "Aldatu aplikazioz"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:54
 | 
			
		||||
#: data/50-mutter-navigation.xml:48
 | 
			
		||||
msgid "Switch to previous application"
 | 
			
		||||
msgstr "Aldatu aurreko aplikaziora"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:58
 | 
			
		||||
#: data/50-mutter-navigation.xml:52
 | 
			
		||||
msgid "Switch windows"
 | 
			
		||||
msgstr "Aldatu leihoz"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:63
 | 
			
		||||
#: data/50-mutter-navigation.xml:57
 | 
			
		||||
msgid "Switch to previous window"
 | 
			
		||||
msgstr "Aldatu aurreko leihora"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:67
 | 
			
		||||
#: data/50-mutter-navigation.xml:61
 | 
			
		||||
msgid "Switch windows of an application"
 | 
			
		||||
msgstr "Aldatu aplikazio baten leihoen artean"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:72
 | 
			
		||||
#: data/50-mutter-navigation.xml:66
 | 
			
		||||
msgid "Switch to previous window of an application"
 | 
			
		||||
msgstr "Aldatu aplikazio baten aurreko leihora"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:76
 | 
			
		||||
#: data/50-mutter-navigation.xml:70
 | 
			
		||||
msgid "Switch system controls"
 | 
			
		||||
msgstr "Aldatu sistemaren kontrolak"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:81
 | 
			
		||||
#: data/50-mutter-navigation.xml:75
 | 
			
		||||
msgid "Switch to previous system control"
 | 
			
		||||
msgstr "Aldatu aurreko sistemaren kontrolera"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:85
 | 
			
		||||
#: data/50-mutter-navigation.xml:79
 | 
			
		||||
msgid "Switch windows directly"
 | 
			
		||||
msgstr "Aldatu leihoa zuzenean"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:90
 | 
			
		||||
#: data/50-mutter-navigation.xml:84
 | 
			
		||||
msgid "Switch directly to previous window"
 | 
			
		||||
msgstr "Aldatu zuzenean aurreko leihora"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:94
 | 
			
		||||
#: data/50-mutter-navigation.xml:88
 | 
			
		||||
msgid "Switch windows of an app directly"
 | 
			
		||||
msgstr "Aldatu aplikazio baten leihoa zuzenean"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:99
 | 
			
		||||
#: data/50-mutter-navigation.xml:93
 | 
			
		||||
msgid "Switch directly to previous window of an app"
 | 
			
		||||
msgstr "Aldatu zuzenean aplik. baten aurreko leihora"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:103
 | 
			
		||||
#: data/50-mutter-navigation.xml:97
 | 
			
		||||
msgid "Switch system controls directly"
 | 
			
		||||
msgstr "Aldatu sistemaren kontrolak zuzenean"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:108
 | 
			
		||||
#: data/50-mutter-navigation.xml:102
 | 
			
		||||
msgid "Switch directly to previous system control"
 | 
			
		||||
msgstr "Aldatu zuzenean aurreko sistemaren kontrolera"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:111
 | 
			
		||||
#: data/50-mutter-navigation.xml:105
 | 
			
		||||
msgid "Hide all normal windows"
 | 
			
		||||
msgstr "Ezkutatu leiho arrunt guztiak"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:114
 | 
			
		||||
#: data/50-mutter-navigation.xml:108
 | 
			
		||||
msgid "Switch to workspace 1"
 | 
			
		||||
msgstr "Aldatu 1. laneko areara"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:117
 | 
			
		||||
#: data/50-mutter-navigation.xml:111
 | 
			
		||||
msgid "Switch to workspace 2"
 | 
			
		||||
msgstr "Aldatu 2. laneko areara"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:120
 | 
			
		||||
#: data/50-mutter-navigation.xml:114
 | 
			
		||||
msgid "Switch to workspace 3"
 | 
			
		||||
msgstr "Aldatu 3. laneko areara"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:123
 | 
			
		||||
#: data/50-mutter-navigation.xml:117
 | 
			
		||||
msgid "Switch to workspace 4"
 | 
			
		||||
msgstr "Aldatu 4. laneko areara"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:126
 | 
			
		||||
#: data/50-mutter-navigation.xml:120
 | 
			
		||||
msgid "Switch to last workspace"
 | 
			
		||||
msgstr "Aldatu azkeneko laneko areara"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:129
 | 
			
		||||
msgid "Move to workspace left"
 | 
			
		||||
msgstr "Eraman ezkerreko laneko areara"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:132
 | 
			
		||||
msgid "Move to workspace right"
 | 
			
		||||
msgstr "Eraman eskuineko laneko areara"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:135
 | 
			
		||||
#: data/50-mutter-navigation.xml:123
 | 
			
		||||
msgid "Move to workspace above"
 | 
			
		||||
msgstr "Eraman gaineko laneko areara"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:138
 | 
			
		||||
#: data/50-mutter-navigation.xml:126
 | 
			
		||||
msgid "Move to workspace below"
 | 
			
		||||
msgstr "Eraman azpiko laneko areara"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-system.xml:6
 | 
			
		||||
#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6
 | 
			
		||||
msgid "System"
 | 
			
		||||
msgstr "Sistema"
 | 
			
		||||
 | 
			
		||||
@@ -185,6 +168,10 @@ msgstr "Erakutsi gonbitea komandoa exekutatzeko"
 | 
			
		||||
msgid "Show the activities overview"
 | 
			
		||||
msgstr "Erakutsi jardueren aurkezpen orokorra"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-wayland.xml:8
 | 
			
		||||
msgid "Restore the keyboard shortcuts"
 | 
			
		||||
msgstr "Leheneratu laster-teklak"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-windows.xml:6
 | 
			
		||||
msgid "Windows"
 | 
			
		||||
msgstr "Leihoak"
 | 
			
		||||
@@ -210,54 +197,50 @@ msgid "Restore window"
 | 
			
		||||
msgstr "Leheneratu leihoa"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-windows.xml:18
 | 
			
		||||
msgid "Toggle shaded state"
 | 
			
		||||
msgstr "Txandakatu bildutako egoera"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-windows.xml:20
 | 
			
		||||
msgid "Close window"
 | 
			
		||||
msgstr "Itxi leihoa"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-windows.xml:22
 | 
			
		||||
#: data/50-mutter-windows.xml:20
 | 
			
		||||
msgid "Hide window"
 | 
			
		||||
msgstr "Ezkutatu leihoa"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-windows.xml:24
 | 
			
		||||
#: data/50-mutter-windows.xml:22
 | 
			
		||||
msgid "Move window"
 | 
			
		||||
msgstr "Aldatu leihoa lekuz"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-windows.xml:26
 | 
			
		||||
#: data/50-mutter-windows.xml:24
 | 
			
		||||
msgid "Resize window"
 | 
			
		||||
msgstr "Aldatu leihoaren tamaina"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-windows.xml:29
 | 
			
		||||
#: data/50-mutter-windows.xml:27
 | 
			
		||||
msgid "Toggle window on all workspaces or one"
 | 
			
		||||
msgstr "Txandakatu leihoa laneko area guztietan edo bakar batean egotea"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-windows.xml:31
 | 
			
		||||
#: data/50-mutter-windows.xml:29
 | 
			
		||||
msgid "Raise window if covered, otherwise lower it"
 | 
			
		||||
msgstr "Goratu leihoa beste leiho batek estaltzen badu, bestela beheratu"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-windows.xml:33
 | 
			
		||||
#: data/50-mutter-windows.xml:31
 | 
			
		||||
msgid "Raise window above other windows"
 | 
			
		||||
msgstr "Goratu leihoa beste leihoen gainera"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-windows.xml:35
 | 
			
		||||
#: data/50-mutter-windows.xml:33
 | 
			
		||||
msgid "Lower window below other windows"
 | 
			
		||||
msgstr "Beheratu leihoa beste leihoen azpira"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-windows.xml:37
 | 
			
		||||
#: data/50-mutter-windows.xml:35
 | 
			
		||||
msgid "Maximize window vertically"
 | 
			
		||||
msgstr "Maximizatu leihoa bertikalki"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-windows.xml:39
 | 
			
		||||
#: data/50-mutter-windows.xml:37
 | 
			
		||||
msgid "Maximize window horizontally"
 | 
			
		||||
msgstr "Maximizatu leihoa horizontalki"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-windows.xml:43
 | 
			
		||||
#: data/50-mutter-windows.xml:41
 | 
			
		||||
msgid "View split on left"
 | 
			
		||||
msgstr "Ikusi zatia ezkerrean"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-windows.xml:47
 | 
			
		||||
#: data/50-mutter-windows.xml:45
 | 
			
		||||
msgid "View split on right"
 | 
			
		||||
msgstr "Ikusi zatia eskuinean"
 | 
			
		||||
 | 
			
		||||
@@ -417,11 +400,9 @@ msgstr ""
 | 
			
		||||
"Eginbideak osatzailea berrabiaraztea behar duen edo ez emandako eginbidearen "
 | 
			
		||||
"arabera dago. Ez da derrigorrezkoa edozer eginbide esperimental eskuragarri "
 | 
			
		||||
"edo konfiguragarria egotea. Ez uste ezarpen honetan edozer gehitzeak "
 | 
			
		||||
"etorkizuneko "
 | 
			
		||||
"proba izango denik. Gako erabilgarriak: "
 | 
			
		||||
"• “scale-monitor-framebuffer” — honek mutter monitoreen diseinu logikoetara "
 | 
			
		||||
"lehenesten du espazioaren koordenatuko pixel logikoetan (leihoaren edukiaren "
 | 
			
		||||
"ordez "
 | 
			
		||||
"etorkizuneko proba izango denik. Gako erabilgarriak: • “scale-monitor-"
 | 
			
		||||
"framebuffer” — honek mutter monitoreen diseinu logikoetara lehenesten du "
 | 
			
		||||
"espazioaren koordenatuko pixel logikoetan (leihoaren edukiaren ordez "
 | 
			
		||||
"monitorearen framebufferra eskalatzean) HiDPI monitoreak kudeatzeko. Ez du "
 | 
			
		||||
"berrabiaraztea eskatzen."
 | 
			
		||||
 | 
			
		||||
@@ -434,7 +415,6 @@ msgid "Cancel tab popup"
 | 
			
		||||
msgstr "Utzi laster-fitxa"
 | 
			
		||||
 | 
			
		||||
#: data/org.gnome.mutter.gschema.xml.in:151
 | 
			
		||||
#| msgid "Switch monitor"
 | 
			
		||||
msgid "Switch monitor configurations"
 | 
			
		||||
msgstr "Aldatu monitorearen konfigurazioak"
 | 
			
		||||
 | 
			
		||||
@@ -494,10 +474,61 @@ msgstr "Aldatu 12. TBra"
 | 
			
		||||
msgid "Re-enable shortcuts"
 | 
			
		||||
msgstr "Gaitu berriro laster-teklak"
 | 
			
		||||
 | 
			
		||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:64
 | 
			
		||||
msgid "Allow grabs with Xwayland"
 | 
			
		||||
msgstr "Baimendu Xwayland-ekin kapturatzea"
 | 
			
		||||
 | 
			
		||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:65
 | 
			
		||||
msgid ""
 | 
			
		||||
"Allow keyboard grabs issued by X11 applications running in Xwayland to be "
 | 
			
		||||
"taken into account. For a X11 grab to be taken into account under Wayland, "
 | 
			
		||||
"the client must also either send a specific X11 ClientMessage to the root "
 | 
			
		||||
"window or be among the applications white-listed in key “xwayland-grab-"
 | 
			
		||||
"access-rules”."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Baimendu Xwayland-en exekutatzen ari diren X11 aplikazioek igorritako "
 | 
			
		||||
"teklatuaren kaptura kontutan hartzea. Wayland pean X11 kapturatzea kontutan "
 | 
			
		||||
"hartzeko bezeroak X11 ClientMessage zehatz bat bidali behar dio leiho"
 | 
			
		||||
" erroari, edo "
 | 
			
		||||
"“xwayland-grab-access-rules” gakoaren zerrenda-zuriko aplikazioen artean egon "
 | 
			
		||||
"behar da."
 | 
			
		||||
 | 
			
		||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:77
 | 
			
		||||
msgid "Xwayland applications allowed to issue keyboard grabs"
 | 
			
		||||
msgstr "Teklatua kaptura dezaketen Xwayland aplikazioak"
 | 
			
		||||
 | 
			
		||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:78
 | 
			
		||||
msgid ""
 | 
			
		||||
"List the resource names or resource class of X11 windows either allowed or "
 | 
			
		||||
"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or "
 | 
			
		||||
"resource class of a given X11 window can be obtained using the command "
 | 
			
		||||
"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. "
 | 
			
		||||
"Values starting with “!” are blacklisted, which has precedence over the "
 | 
			
		||||
"whitelist, to revoke applications from the default system list. The default "
 | 
			
		||||
"system list includes the following applications: "
 | 
			
		||||
"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by "
 | 
			
		||||
"using the specific keyboard shortcut defined by the keybinding key “restore-"
 | 
			
		||||
"shortcuts”."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Xwayland pean teklatuaren kapturatzeko baimendutako edo ez baimendutako "
 | 
			
		||||
"X11 leihoen baliabide-izenen edo baliabide-klaseen zerrenda. X11 leihoen"
 | 
			
		||||
" baliabide-izenak "
 | 
			
		||||
"edo baliabide-klaseak eskuratzeko exekutatu “xprop WM_CLASS” komandoa. "
 | 
			
		||||
"“*” eta “?” komodinak onartuta daude. “!” karakterearekin hasten diren"
 | 
			
		||||
" balioak "
 | 
			
		||||
"zerrenda beltzean daude, zerrenda zurikoei aurre hartzen dietelarik,"
 | 
			
		||||
" sistemako "
 | 
			
		||||
"zerrenda lehenetsitik aplikazioak errebokatzeko. Sistemako zerrenda"
 | 
			
		||||
" lehenetsiak honako "
 | 
			
		||||
"aplikazioak ditu: “@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” "
 | 
			
		||||
"Erabiltzaileek existitzen den kaptura bat hauts dezakete “restore-shortcuts”"
 | 
			
		||||
" gakoan "
 | 
			
		||||
"zehaztutako laster-tekla zehatza erabiliz."
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: This string refers to a button that switches between
 | 
			
		||||
#. * different modes.
 | 
			
		||||
#.
 | 
			
		||||
#: src/backends/meta-input-settings.c:2151
 | 
			
		||||
#: src/backends/meta-input-settings.c:2310
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Mode Switch (Group %d)"
 | 
			
		||||
msgstr "Modu aldaketa (%d taldea)"
 | 
			
		||||
@@ -505,37 +536,37 @@ msgstr "Modu aldaketa (%d taldea)"
 | 
			
		||||
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
 | 
			
		||||
#. * mapping through the available outputs.
 | 
			
		||||
#.
 | 
			
		||||
#: src/backends/meta-input-settings.c:2174
 | 
			
		||||
#: src/backends/meta-input-settings.c:2333
 | 
			
		||||
msgid "Switch monitor"
 | 
			
		||||
msgstr "Aldatu monitorea"
 | 
			
		||||
 | 
			
		||||
#: src/backends/meta-input-settings.c:2176
 | 
			
		||||
#: src/backends/meta-input-settings.c:2335
 | 
			
		||||
msgid "Show on-screen help"
 | 
			
		||||
msgstr "Erakutsi pantailako laguntza"
 | 
			
		||||
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:903
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:888
 | 
			
		||||
msgid "Built-in display"
 | 
			
		||||
msgstr "Bertako pantaila"
 | 
			
		||||
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:926
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:911
 | 
			
		||||
msgid "Unknown"
 | 
			
		||||
msgstr "Ezezaguna"
 | 
			
		||||
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:928
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:913
 | 
			
		||||
msgid "Unknown Display"
 | 
			
		||||
msgstr "Pantaila ezezaguna"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
 | 
			
		||||
#. * size in inches, like 'Dell 15"'
 | 
			
		||||
#.
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:936
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:921
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s %s"
 | 
			
		||||
msgstr "%s %s"
 | 
			
		||||
 | 
			
		||||
#. This probably means that a non-WM compositor like xcompmgr is running;
 | 
			
		||||
#. * we have no way to get it to exit
 | 
			
		||||
#: src/compositor/compositor.c:476
 | 
			
		||||
#: src/compositor/compositor.c:481
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"Another compositing manager is already running on screen %i on display “%s”."
 | 
			
		||||
@@ -543,62 +574,65 @@ msgstr ""
 | 
			
		||||
"Dagoeneko beste konposatze-kudeatzailea ari da exekutatzen “%2$s“ pantailako "
 | 
			
		||||
"%1$i. monitorean."
 | 
			
		||||
 | 
			
		||||
#: src/core/bell.c:194
 | 
			
		||||
#: src/core/bell.c:254
 | 
			
		||||
msgid "Bell event"
 | 
			
		||||
msgstr "Soinuaren gertaera"
 | 
			
		||||
 | 
			
		||||
#: src/core/display.c:608
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Failed to open X Window System display “%s”\n"
 | 
			
		||||
msgstr "Huts egin du X Window sistemaren “%s“ pantaila irekitzean\n"
 | 
			
		||||
 | 
			
		||||
#: src/core/main.c:189
 | 
			
		||||
#: src/core/main.c:191
 | 
			
		||||
msgid "Disable connection to session manager"
 | 
			
		||||
msgstr "Desgaitu saio-kudeatzailearen konexioa"
 | 
			
		||||
 | 
			
		||||
#: src/core/main.c:195
 | 
			
		||||
#: src/core/main.c:197
 | 
			
		||||
msgid "Replace the running window manager"
 | 
			
		||||
msgstr "Ordeztu exekutatzen dagoen leiho-kudeatzailea"
 | 
			
		||||
 | 
			
		||||
#: src/core/main.c:201
 | 
			
		||||
#: src/core/main.c:203
 | 
			
		||||
msgid "Specify session management ID"
 | 
			
		||||
msgstr "Zehaztu saio-kudeatzailearen IDa"
 | 
			
		||||
 | 
			
		||||
#: src/core/main.c:206
 | 
			
		||||
#: src/core/main.c:208
 | 
			
		||||
msgid "X Display to use"
 | 
			
		||||
msgstr "X pantaila erabiltzeko"
 | 
			
		||||
 | 
			
		||||
#: src/core/main.c:212
 | 
			
		||||
#: src/core/main.c:214
 | 
			
		||||
msgid "Initialize session from savefile"
 | 
			
		||||
msgstr "Hasieratu saioa babes-fitxategitik"
 | 
			
		||||
 | 
			
		||||
#: src/core/main.c:218
 | 
			
		||||
#: src/core/main.c:220
 | 
			
		||||
msgid "Make X calls synchronous"
 | 
			
		||||
msgstr "Egin X deiak sinkronoak izatea"
 | 
			
		||||
 | 
			
		||||
#: src/core/main.c:225
 | 
			
		||||
#: src/core/main.c:227
 | 
			
		||||
msgid "Run as a wayland compositor"
 | 
			
		||||
msgstr "Exekutatu wayland konposatzaile gisa"
 | 
			
		||||
 | 
			
		||||
#: src/core/main.c:231
 | 
			
		||||
#: src/core/main.c:233
 | 
			
		||||
msgid "Run as a nested compositor"
 | 
			
		||||
msgstr "Exekutatu habiaratutako konposatzaile gisa"
 | 
			
		||||
 | 
			
		||||
#: src/core/main.c:239
 | 
			
		||||
msgid "Run wayland compositor without starting Xwayland"
 | 
			
		||||
msgstr "Exekutatu wayland-en konposatzailea Xwayland abiarazi gabe"
 | 
			
		||||
 | 
			
		||||
#: src/core/main.c:247
 | 
			
		||||
msgid "Run as a full display server, rather than nested"
 | 
			
		||||
msgstr "Exekutatu pantaila-zerbitzari oso bezala, habiaratuta baino"
 | 
			
		||||
 | 
			
		||||
#: src/core/main.c:253
 | 
			
		||||
msgid "Run with X11 backend"
 | 
			
		||||
msgstr "Exekutatu X11 motorrarekin"
 | 
			
		||||
 | 
			
		||||
#. Translators: %s is a window title
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:147
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:148
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "“%s” is not responding."
 | 
			
		||||
msgstr "'%s'(e)k ez du erantzuten."
 | 
			
		||||
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:149
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:150
 | 
			
		||||
msgid "Application is not responding."
 | 
			
		||||
msgstr "Aplikazioak ez du erantzuten."
 | 
			
		||||
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:154
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:155
 | 
			
		||||
msgid ""
 | 
			
		||||
"You may choose to wait a short while for it to continue or force the "
 | 
			
		||||
"application to quit entirely."
 | 
			
		||||
@@ -606,11 +640,11 @@ msgstr ""
 | 
			
		||||
"Aukeratu piskatean zai egotea aplikazioak jarraitzeko edo derrigortu "
 | 
			
		||||
"aplikazioa erabat ixtea."
 | 
			
		||||
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:161
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:162
 | 
			
		||||
msgid "_Force Quit"
 | 
			
		||||
msgstr "_Behartu ixtera"
 | 
			
		||||
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:161
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:162
 | 
			
		||||
msgid "_Wait"
 | 
			
		||||
msgstr "_Itxaron"
 | 
			
		||||
 | 
			
		||||
@@ -637,12 +671,21 @@ msgstr "Erakutsi bertsioa"
 | 
			
		||||
msgid "Mutter plugin to use"
 | 
			
		||||
msgstr "Mutter-en osagaia erabiltzeko"
 | 
			
		||||
 | 
			
		||||
#: src/core/prefs.c:1997
 | 
			
		||||
#: src/core/prefs.c:1787
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Workspace %d"
 | 
			
		||||
msgstr "%d. laneko area"
 | 
			
		||||
 | 
			
		||||
#: src/core/screen.c:580
 | 
			
		||||
#: src/core/util.c:120
 | 
			
		||||
msgid "Mutter was compiled without support for verbose mode\n"
 | 
			
		||||
msgstr "Mutter modu xehatuaren euskarririk gabe konpilatu da\n"
 | 
			
		||||
 | 
			
		||||
#: src/wayland/meta-wayland-tablet-pad.c:567
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Mode Switch: Mode %d"
 | 
			
		||||
msgstr "Modu aldaketa: %d modua"
 | 
			
		||||
 | 
			
		||||
#: src/x11/meta-x11-display.c:666
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"Display “%s” already has a window manager; try using the --replace option to "
 | 
			
		||||
@@ -651,21 +694,21 @@ msgstr ""
 | 
			
		||||
"“%s“ pantailak badu leiho-kudeatzailea; erabili --replace aukera uneko leiho-"
 | 
			
		||||
"kudeatzailea ordezteko."
 | 
			
		||||
 | 
			
		||||
#: src/core/screen.c:665
 | 
			
		||||
#: src/x11/meta-x11-display.c:1010
 | 
			
		||||
msgid "Failed to initialize GDK\n"
 | 
			
		||||
msgstr "Huts egin du GDK hasieratzean\n"
 | 
			
		||||
 | 
			
		||||
#: src/x11/meta-x11-display.c:1034
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Failed to open X Window System display “%s”\n"
 | 
			
		||||
msgstr "Huts egin du X Window sistemaren “%s“ pantaila irekitzean\n"
 | 
			
		||||
 | 
			
		||||
#: src/x11/meta-x11-display.c:1117
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Screen %d on display “%s” is invalid\n"
 | 
			
		||||
msgstr "“%2$s“ bistaratzeko %1$d pantaila ez da baliozkoa\n"
 | 
			
		||||
 | 
			
		||||
#: src/core/util.c:120
 | 
			
		||||
msgid "Mutter was compiled without support for verbose mode\n"
 | 
			
		||||
msgstr "Mutter modu xehatuaren euskarririk gabe konpilatu da\n"
 | 
			
		||||
 | 
			
		||||
#: src/wayland/meta-wayland-tablet-pad.c:563
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Mode Switch: Mode %d"
 | 
			
		||||
msgstr "Modu aldaketa: %d modua"
 | 
			
		||||
 | 
			
		||||
#: src/x11/session.c:1815
 | 
			
		||||
#: src/x11/session.c:1819
 | 
			
		||||
msgid ""
 | 
			
		||||
"These windows do not support “save current setup” and will have to be "
 | 
			
		||||
"restarted manually next time you log in."
 | 
			
		||||
@@ -673,11 +716,26 @@ msgstr ""
 | 
			
		||||
"Leiho hauek ez dute onartzen “gorde uneko konfigurazioa“; eta eskuz "
 | 
			
		||||
"berrabiarazi beharko dituzu hurrengo saioa hasten duzunean."
 | 
			
		||||
 | 
			
		||||
#: src/x11/window-props.c:559
 | 
			
		||||
#: src/x11/window-props.c:565
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s (on %s)"
 | 
			
		||||
msgstr "%s (%s)"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Move window one workspace to the left"
 | 
			
		||||
#~ msgstr "Eraman leihoa laneko area bat ezkerrera"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Move window one workspace to the right"
 | 
			
		||||
#~ msgstr "Eraman leihoa laneko area bat eskuinera"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Move to workspace left"
 | 
			
		||||
#~ msgstr "Eraman ezkerreko laneko areara"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Move to workspace right"
 | 
			
		||||
#~ msgstr "Eraman eskuineko laneko areara"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Toggle shaded state"
 | 
			
		||||
#~ msgstr "Txandakatu bildutako egoera"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Failed to scan themes directory: %s\n"
 | 
			
		||||
#~ msgstr "Huts egin du gaien direktorioa aztertzean: %s\n"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								po/fr.po
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								po/fr.po
									
									
									
									
									
								
							@@ -14,21 +14,22 @@
 | 
			
		||||
# Claude Paroz <claude@2xlibre.net>, 2008-2018.
 | 
			
		||||
# Bruno Brouard <annoa.b@gmail.com>, 2011-12.
 | 
			
		||||
# Jean-Baptiste Holcroft <jean-baptiste@holcroft.fr>, 2017.
 | 
			
		||||
# Charles Monzat <superboa@hotmail.fr>, 2016, 2017.
 | 
			
		||||
# Charles Monzat <charles.monzat@numericable.fr>, 2016-2018.
 | 
			
		||||
#
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: mutter master\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2018-07-07 09:58+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2018-07-24 10:22+0200\n"
 | 
			
		||||
"Last-Translator: Claude Paroz <claude@2xlibre.net>\n"
 | 
			
		||||
"POT-Creation-Date: 2018-11-13 22:58+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2018-11-15 22:09+0100\n"
 | 
			
		||||
"Last-Translator: Charles Monzat <charles.monzat@numericable.fr>\n"
 | 
			
		||||
"Language-Team: français <gnomefr@traduc.org>\n"
 | 
			
		||||
"Language: fr\n"
 | 
			
		||||
"MIME-Version: 1.0\n"
 | 
			
		||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
			
		||||
"Content-Transfer-Encoding: 8bit\n"
 | 
			
		||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
 | 
			
		||||
"X-Generator: Gtranslator 3.30.0\n"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:6
 | 
			
		||||
msgid "Navigation"
 | 
			
		||||
@@ -531,7 +532,7 @@ msgstr ""
 | 
			
		||||
"autorisées ou non à émettre des captures clavier sous Xwayland. Le nom ou la "
 | 
			
		||||
"classe de ressource d’une fenêtre X11 donnée peut être obtenue à l’aide de "
 | 
			
		||||
"la commande « xprop WM_CLASS ». Les caractères joker « * » et « ? » sont "
 | 
			
		||||
"acceptées dans les valeurs. Les valeurs commençant pas « ! » sont en liste "
 | 
			
		||||
"acceptées dans les valeurs. Les valeurs commençant par « ! » sont en liste "
 | 
			
		||||
"noire, qui a priorité sur la liste blanche, pour révoquer les applications "
 | 
			
		||||
"de la liste système par défaut. Celle-ci contient les applications "
 | 
			
		||||
"suivantes : « @XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@ ». Les utilisateurs "
 | 
			
		||||
@@ -541,7 +542,7 @@ msgstr ""
 | 
			
		||||
#. TRANSLATORS: This string refers to a button that switches between
 | 
			
		||||
#. * different modes.
 | 
			
		||||
#.
 | 
			
		||||
#: src/backends/meta-input-settings.c:2325
 | 
			
		||||
#: src/backends/meta-input-settings.c:2310
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Mode Switch (Group %d)"
 | 
			
		||||
msgstr "Changement de mode (groupe %d)"
 | 
			
		||||
@@ -549,30 +550,30 @@ msgstr "Changement de mode (groupe %d)"
 | 
			
		||||
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
 | 
			
		||||
#. * mapping through the available outputs.
 | 
			
		||||
#.
 | 
			
		||||
#: src/backends/meta-input-settings.c:2348
 | 
			
		||||
#: src/backends/meta-input-settings.c:2333
 | 
			
		||||
msgid "Switch monitor"
 | 
			
		||||
msgstr "Changer de moniteur"
 | 
			
		||||
 | 
			
		||||
#: src/backends/meta-input-settings.c:2350
 | 
			
		||||
#: src/backends/meta-input-settings.c:2335
 | 
			
		||||
msgid "Show on-screen help"
 | 
			
		||||
msgstr "Afficher l’aide à l’écran"
 | 
			
		||||
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:907
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:888
 | 
			
		||||
msgid "Built-in display"
 | 
			
		||||
msgstr "Affichage intégré"
 | 
			
		||||
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:930
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:911
 | 
			
		||||
msgid "Unknown"
 | 
			
		||||
msgstr "Inconnu"
 | 
			
		||||
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:932
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:913
 | 
			
		||||
msgid "Unknown Display"
 | 
			
		||||
msgstr "Affichage inconnu"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
 | 
			
		||||
#. * size in inches, like 'Dell 15"'
 | 
			
		||||
#.
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:940
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:921
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s %s"
 | 
			
		||||
msgstr "%s %s"
 | 
			
		||||
@@ -685,7 +686,7 @@ msgstr "Afficher la version"
 | 
			
		||||
msgid "Mutter plugin to use"
 | 
			
		||||
msgstr "Greffon de Mutter à utiliser"
 | 
			
		||||
 | 
			
		||||
#: src/core/prefs.c:1915
 | 
			
		||||
#: src/core/prefs.c:1787
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Workspace %d"
 | 
			
		||||
msgstr "Espace de travail %d"
 | 
			
		||||
@@ -699,7 +700,7 @@ msgstr "Mutter a été compilé sans la prise en charge du mode bavard\n"
 | 
			
		||||
msgid "Mode Switch: Mode %d"
 | 
			
		||||
msgstr "Changement de mode : mode %d"
 | 
			
		||||
 | 
			
		||||
#: src/x11/meta-x11-display.c:666
 | 
			
		||||
#: src/x11/meta-x11-display.c:672
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"Display “%s” already has a window manager; try using the --replace option to "
 | 
			
		||||
@@ -708,16 +709,16 @@ msgstr ""
 | 
			
		||||
"L’affichage « %s » a déjà un gestionnaire de fenêtres ; essayez d’utiliser "
 | 
			
		||||
"l’option --replace pour remplacer le gestionnaire de fenêtres actuel."
 | 
			
		||||
 | 
			
		||||
#: src/x11/meta-x11-display.c:1010
 | 
			
		||||
#: src/x11/meta-x11-display.c:1016
 | 
			
		||||
msgid "Failed to initialize GDK\n"
 | 
			
		||||
msgstr "L’initialisation de GDK a échoué\n"
 | 
			
		||||
 | 
			
		||||
#: src/x11/meta-x11-display.c:1034
 | 
			
		||||
#: src/x11/meta-x11-display.c:1040
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Failed to open X Window System display “%s”\n"
 | 
			
		||||
msgstr "Impossible d’ouvrir l’affichage « %s » du système X Window\n"
 | 
			
		||||
 | 
			
		||||
#: src/x11/meta-x11-display.c:1117
 | 
			
		||||
#: src/x11/meta-x11-display.c:1123
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Screen %d on display “%s” is invalid\n"
 | 
			
		||||
msgstr "L’écran %d sur l’affichage « %s » n’est pas valide\n"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										113
									
								
								po/sk.po
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								po/sk.po
									
									
									
									
									
								
							@@ -13,8 +13,8 @@ msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: mutter\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2018-02-06 04:14+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2018-03-17 21:52+0100\n"
 | 
			
		||||
"POT-Creation-Date: 2018-10-22 16:18+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2018-10-27 21:19+0200\n"
 | 
			
		||||
"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
 | 
			
		||||
"Language-Team: Slovak <gnome-sk-list@gnome.org>\n"
 | 
			
		||||
"Language: sk\n"
 | 
			
		||||
@@ -22,7 +22,7 @@ msgstr ""
 | 
			
		||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
			
		||||
"Content-Transfer-Encoding: 8bit\n"
 | 
			
		||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n"
 | 
			
		||||
"X-Generator: Poedit 2.0.6\n"
 | 
			
		||||
"X-Generator: Poedit 2.2\n"
 | 
			
		||||
 | 
			
		||||
#: data/50-mutter-navigation.xml:6
 | 
			
		||||
msgid "Navigation"
 | 
			
		||||
@@ -468,29 +468,26 @@ msgid ""
 | 
			
		||||
"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes "
 | 
			
		||||
"mutter default to layout logical monitors in a logical pixel coordinate "
 | 
			
		||||
"space, while scaling monitor framebuffers instead of window content, to "
 | 
			
		||||
"manage HiDPI monitors. Does not require a restart. • “remote-desktop” — "
 | 
			
		||||
"enables remote desktop support. To support remote desktop with screen "
 | 
			
		||||
"sharing, “screen-cast” must also be enabled. • “screen-cast” — enables "
 | 
			
		||||
"screen cast support."
 | 
			
		||||
"manage HiDPI monitors. Does not require a restart."
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
# summary
 | 
			
		||||
#: data/org.gnome.mutter.gschema.xml.in:145
 | 
			
		||||
#: data/org.gnome.mutter.gschema.xml.in:141
 | 
			
		||||
msgid "Select window from tab popup"
 | 
			
		||||
msgstr "Vybrať okno z rozbaľovacej ponuky tabulátora"
 | 
			
		||||
 | 
			
		||||
# summary
 | 
			
		||||
#: data/org.gnome.mutter.gschema.xml.in:150
 | 
			
		||||
#: data/org.gnome.mutter.gschema.xml.in:146
 | 
			
		||||
msgid "Cancel tab popup"
 | 
			
		||||
msgstr "Zrušit rozbaľovaciu ponuku tabulátora"
 | 
			
		||||
 | 
			
		||||
# PK: predpokladam ze to prepisane medzi tlacidlami
 | 
			
		||||
# description
 | 
			
		||||
#: data/org.gnome.mutter.gschema.xml.in:155
 | 
			
		||||
#: data/org.gnome.mutter.gschema.xml.in:151
 | 
			
		||||
msgid "Switch monitor configurations"
 | 
			
		||||
msgstr "Prepnúť nastavenia monitorov"
 | 
			
		||||
 | 
			
		||||
#: data/org.gnome.mutter.gschema.xml.in:160
 | 
			
		||||
#: data/org.gnome.mutter.gschema.xml.in:156
 | 
			
		||||
msgid "Rotates the built-in monitor configuration"
 | 
			
		||||
msgstr "Otočí nastavenie vstavaného monitora"
 | 
			
		||||
 | 
			
		||||
@@ -587,7 +584,7 @@ msgstr ""
 | 
			
		||||
#. TRANSLATORS: This string refers to a button that switches between
 | 
			
		||||
#. * different modes.
 | 
			
		||||
#.
 | 
			
		||||
#: src/backends/meta-input-settings.c:2260
 | 
			
		||||
#: src/backends/meta-input-settings.c:2310
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Mode Switch (Group %d)"
 | 
			
		||||
msgstr "Prepínač režimu (skupina č. %d)"
 | 
			
		||||
@@ -597,30 +594,30 @@ msgstr "Prepínač režimu (skupina č. %d)"
 | 
			
		||||
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
 | 
			
		||||
#. * mapping through the available outputs.
 | 
			
		||||
#.
 | 
			
		||||
#: src/backends/meta-input-settings.c:2283
 | 
			
		||||
#: src/backends/meta-input-settings.c:2333
 | 
			
		||||
msgid "Switch monitor"
 | 
			
		||||
msgstr "Prepnúť monitor"
 | 
			
		||||
 | 
			
		||||
#: src/backends/meta-input-settings.c:2285
 | 
			
		||||
#: src/backends/meta-input-settings.c:2335
 | 
			
		||||
msgid "Show on-screen help"
 | 
			
		||||
msgstr "Zobraziť pomocníka na obrazovke"
 | 
			
		||||
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:900
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:888
 | 
			
		||||
msgid "Built-in display"
 | 
			
		||||
msgstr "Vstavaný displej"
 | 
			
		||||
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:923
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:911
 | 
			
		||||
msgid "Unknown"
 | 
			
		||||
msgstr "Neznámy"
 | 
			
		||||
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:925
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:913
 | 
			
		||||
msgid "Unknown Display"
 | 
			
		||||
msgstr "Neznámy displej"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
 | 
			
		||||
#. * size in inches, like 'Dell 15"'
 | 
			
		||||
#.
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:933
 | 
			
		||||
#: src/backends/meta-monitor-manager.c:921
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s %s"
 | 
			
		||||
msgstr "%s %s"
 | 
			
		||||
@@ -634,86 +631,84 @@ msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Pre obrazovku č. %i na displeji „%s“ je spustený už iný správca rozloženia."
 | 
			
		||||
 | 
			
		||||
#: src/core/bell.c:194
 | 
			
		||||
#: src/core/bell.c:254
 | 
			
		||||
msgid "Bell event"
 | 
			
		||||
msgstr "Udalosť zvončeka"
 | 
			
		||||
 | 
			
		||||
# X window system preloz, napr. system na spravu okien X
 | 
			
		||||
#: src/core/display.c:608
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Failed to open X Window System display “%s”\n"
 | 
			
		||||
msgstr "Zlyhalo otvorenie displeja systému na správu okien X „%s“\n"
 | 
			
		||||
 | 
			
		||||
# cmd desc
 | 
			
		||||
#: src/core/main.c:190
 | 
			
		||||
#: src/core/main.c:191
 | 
			
		||||
msgid "Disable connection to session manager"
 | 
			
		||||
msgstr "Zakáže pripojenia k správcovi relácií"
 | 
			
		||||
 | 
			
		||||
# cmd desc
 | 
			
		||||
#: src/core/main.c:196
 | 
			
		||||
#: src/core/main.c:197
 | 
			
		||||
msgid "Replace the running window manager"
 | 
			
		||||
msgstr "Nahradí bežiaceho správcu okien"
 | 
			
		||||
 | 
			
		||||
# cmd desc
 | 
			
		||||
#: src/core/main.c:202
 | 
			
		||||
#: src/core/main.c:203
 | 
			
		||||
msgid "Specify session management ID"
 | 
			
		||||
msgstr "Zadá identifikátor správy relácií"
 | 
			
		||||
 | 
			
		||||
#: src/core/main.c:207
 | 
			
		||||
#: src/core/main.c:208
 | 
			
		||||
msgid "X Display to use"
 | 
			
		||||
msgstr "X displej, ktorý bude použitý"
 | 
			
		||||
 | 
			
		||||
# cmd desc
 | 
			
		||||
#: src/core/main.c:213
 | 
			
		||||
#: src/core/main.c:214
 | 
			
		||||
msgid "Initialize session from savefile"
 | 
			
		||||
msgstr "Inicializuje reláciu z uloženého súboru"
 | 
			
		||||
 | 
			
		||||
# cmd desc
 | 
			
		||||
#: src/core/main.c:219
 | 
			
		||||
#: src/core/main.c:220
 | 
			
		||||
msgid "Make X calls synchronous"
 | 
			
		||||
msgstr "Použije synchrónne volania X"
 | 
			
		||||
 | 
			
		||||
# cmd desc
 | 
			
		||||
#: src/core/main.c:226
 | 
			
		||||
#: src/core/main.c:227
 | 
			
		||||
msgid "Run as a wayland compositor"
 | 
			
		||||
msgstr "Spustí ako kompozitor protokolu wayland"
 | 
			
		||||
 | 
			
		||||
# cmd desc
 | 
			
		||||
#: src/core/main.c:232
 | 
			
		||||
#: src/core/main.c:233
 | 
			
		||||
msgid "Run as a nested compositor"
 | 
			
		||||
msgstr "Spustí ako kompozitor s vnoreným režimom"
 | 
			
		||||
 | 
			
		||||
#: src/core/main.c:240
 | 
			
		||||
#: src/core/main.c:239
 | 
			
		||||
msgid "Run wayland compositor without starting Xwayland"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: src/core/main.c:247
 | 
			
		||||
msgid "Run as a full display server, rather than nested"
 | 
			
		||||
msgstr "Spustí ako plnohodnotný zobrazovací server, namiesto vnoreného režimu"
 | 
			
		||||
 | 
			
		||||
#: src/core/main.c:246
 | 
			
		||||
#: src/core/main.c:253
 | 
			
		||||
msgid "Run with X11 backend"
 | 
			
		||||
msgstr "Spustí s obslužným programom X11"
 | 
			
		||||
 | 
			
		||||
# %s is a window title
 | 
			
		||||
#. Translators: %s is a window title
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:147
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:148
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "“%s” is not responding."
 | 
			
		||||
msgstr "„%s“ neodpovedá."
 | 
			
		||||
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:149
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:150
 | 
			
		||||
msgid "Application is not responding."
 | 
			
		||||
msgstr "Aplikácia neodpovedá."
 | 
			
		||||
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:154
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:155
 | 
			
		||||
msgid ""
 | 
			
		||||
"You may choose to wait a short while for it to continue or force the "
 | 
			
		||||
"application to quit entirely."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Môžete chvíľu počkať na pokračovanie aplikácie, alebo ju môžete ukončiť."
 | 
			
		||||
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:161
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:162
 | 
			
		||||
msgid "_Force Quit"
 | 
			
		||||
msgstr "_Vynútiť ukončenie"
 | 
			
		||||
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:161
 | 
			
		||||
#: src/core/meta-close-dialog-default.c:162
 | 
			
		||||
msgid "_Wait"
 | 
			
		||||
msgstr "_Počkať"
 | 
			
		||||
 | 
			
		||||
@@ -742,12 +737,21 @@ msgstr "Zobrazí verziu"
 | 
			
		||||
msgid "Mutter plugin to use"
 | 
			
		||||
msgstr "Použije zásuvný modul Mutter"
 | 
			
		||||
 | 
			
		||||
#: src/core/prefs.c:1997
 | 
			
		||||
#: src/core/prefs.c:1787
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Workspace %d"
 | 
			
		||||
msgstr "Pracovný priestor č. %d"
 | 
			
		||||
 | 
			
		||||
#: src/core/screen.c:583
 | 
			
		||||
#: src/core/util.c:120
 | 
			
		||||
msgid "Mutter was compiled without support for verbose mode\n"
 | 
			
		||||
msgstr "Mutter bol skompilovaný bez výpisu podrobností pri behu\n"
 | 
			
		||||
 | 
			
		||||
#: src/wayland/meta-wayland-tablet-pad.c:567
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Mode Switch: Mode %d"
 | 
			
		||||
msgstr "Prepínač režimu: Režim č. %d"
 | 
			
		||||
 | 
			
		||||
#: src/x11/meta-x11-display.c:666
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"Display “%s” already has a window manager; try using the --replace option to "
 | 
			
		||||
@@ -756,21 +760,22 @@ msgstr ""
 | 
			
		||||
"Displej „%s“ už má správcu okien. Skúste použiť prepínač --replace, aby sa "
 | 
			
		||||
"aktuálny správca nahradil."
 | 
			
		||||
 | 
			
		||||
#: src/core/screen.c:668
 | 
			
		||||
#: src/x11/meta-x11-display.c:1010
 | 
			
		||||
msgid "Failed to initialize GDK\n"
 | 
			
		||||
msgstr "Zlyhala inicializácia rozhrania GDK\n"
 | 
			
		||||
 | 
			
		||||
# X window system preloz, napr. system na spravu okien X
 | 
			
		||||
#: src/x11/meta-x11-display.c:1034
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Failed to open X Window System display “%s”\n"
 | 
			
		||||
msgstr "Zlyhalo otvorenie displeja systému na správu okien X „%s“\n"
 | 
			
		||||
 | 
			
		||||
#: src/x11/meta-x11-display.c:1117
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Screen %d on display “%s” is invalid\n"
 | 
			
		||||
msgstr "Obrazovka č. %d na displeji „%s“ nie je platná\n"
 | 
			
		||||
 | 
			
		||||
#: src/core/util.c:120
 | 
			
		||||
msgid "Mutter was compiled without support for verbose mode\n"
 | 
			
		||||
msgstr "Mutter bol skompilovaný bez výpisu podrobností pri behu\n"
 | 
			
		||||
 | 
			
		||||
#: src/wayland/meta-wayland-tablet-pad.c:563
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Mode Switch: Mode %d"
 | 
			
		||||
msgstr "Prepínač režimu: Režim č. %d"
 | 
			
		||||
 | 
			
		||||
#: src/x11/session.c:1818
 | 
			
		||||
#: src/x11/session.c:1819
 | 
			
		||||
msgid ""
 | 
			
		||||
"These windows do not support “save current setup” and will have to be "
 | 
			
		||||
"restarted manually next time you log in."
 | 
			
		||||
@@ -779,7 +784,7 @@ msgstr ""
 | 
			
		||||
"prihlásení ich budete musieť znovu spustiť ručne."
 | 
			
		||||
 | 
			
		||||
# window title; wm_client_machine
 | 
			
		||||
#: src/x11/window-props.c:559
 | 
			
		||||
#: src/x11/window-props.c:565
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s (on %s)"
 | 
			
		||||
msgstr "%s (na %s)"
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,13 @@ dist_stacking_DATA =						\
 | 
			
		||||
	$(srcdir)/tests/stacking/basic-x11.metatest 	\
 | 
			
		||||
	$(srcdir)/tests/stacking/basic-wayland.metatest	\
 | 
			
		||||
	$(srcdir)/tests/stacking/closed-transient.metatest	\
 | 
			
		||||
	$(srcdir)/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest	\
 | 
			
		||||
	$(srcdir)/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest	\
 | 
			
		||||
	$(srcdir)/tests/stacking/closed-transient-no-input-parent.metatest	\
 | 
			
		||||
	$(srcdir)/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest	\
 | 
			
		||||
	$(srcdir)/tests/stacking/closed-transient-no-input-parents.metatest	\
 | 
			
		||||
	$(srcdir)/tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest	\
 | 
			
		||||
	$(srcdir)/tests/stacking/closed-transient-only-take-focus-parents.metatest	\
 | 
			
		||||
	$(srcdir)/tests/stacking/minimized.metatest 	\
 | 
			
		||||
	$(srcdir)/tests/stacking/mixed-windows.metatest     \
 | 
			
		||||
	$(srcdir)/tests/stacking/set-parent.metatest	\
 | 
			
		||||
 
 | 
			
		||||
@@ -51,6 +51,14 @@
 | 
			
		||||
#define META_TYPE_BACKEND (meta_backend_get_type ())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (MetaBackend, meta_backend, META, BACKEND, GObject)
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
  META_SEQUENCE_NONE,
 | 
			
		||||
  META_SEQUENCE_ACCEPTED,
 | 
			
		||||
  META_SEQUENCE_REJECTED,
 | 
			
		||||
  META_SEQUENCE_PENDING_END
 | 
			
		||||
} MetaSequenceState;
 | 
			
		||||
 | 
			
		||||
struct _MetaBackendClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
@@ -73,6 +81,10 @@ struct _MetaBackendClass
 | 
			
		||||
                              int          device_id,
 | 
			
		||||
                              uint32_t     timestamp);
 | 
			
		||||
 | 
			
		||||
  void (* finish_touch_sequence) (MetaBackend          *backend,
 | 
			
		||||
                                  ClutterEventSequence *sequence,
 | 
			
		||||
                                  MetaSequenceState     state);
 | 
			
		||||
 | 
			
		||||
  void (* warp_pointer) (MetaBackend *backend,
 | 
			
		||||
                         int          x,
 | 
			
		||||
                         int          y);
 | 
			
		||||
@@ -136,6 +148,10 @@ gboolean meta_backend_ungrab_device (MetaBackend *backend,
 | 
			
		||||
                                     int          device_id,
 | 
			
		||||
                                     uint32_t     timestamp);
 | 
			
		||||
 | 
			
		||||
void meta_backend_finish_touch_sequence (MetaBackend          *backend,
 | 
			
		||||
                                         ClutterEventSequence *sequence,
 | 
			
		||||
                                         MetaSequenceState     state);
 | 
			
		||||
 | 
			
		||||
void meta_backend_warp_pointer (MetaBackend *backend,
 | 
			
		||||
                                int          x,
 | 
			
		||||
                                int          y);
 | 
			
		||||
 
 | 
			
		||||
@@ -960,6 +960,20 @@ meta_backend_ungrab_device (MetaBackend *backend,
 | 
			
		||||
  return META_BACKEND_GET_CLASS (backend)->ungrab_device (backend, device_id, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_backend_finish_touch_sequence: (skip)
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_backend_finish_touch_sequence (MetaBackend          *backend,
 | 
			
		||||
                                    ClutterEventSequence *sequence,
 | 
			
		||||
                                    MetaSequenceState     state)
 | 
			
		||||
{
 | 
			
		||||
  if (META_BACKEND_GET_CLASS (backend)->finish_touch_sequence)
 | 
			
		||||
    META_BACKEND_GET_CLASS (backend)->finish_touch_sequence (backend,
 | 
			
		||||
                                                             sequence,
 | 
			
		||||
                                                             state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_backend_warp_pointer: (skip)
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
@@ -561,9 +561,7 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
 | 
			
		||||
      g_clear_object (&config);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  config =
 | 
			
		||||
    meta_monitor_config_manager_create_for_switch_config (manager->config_manager,
 | 
			
		||||
                                                          META_MONITOR_SWITCH_CONFIG_ALL_LINEAR);
 | 
			
		||||
  config = meta_monitor_config_manager_create_linear (manager->config_manager);
 | 
			
		||||
  if (config)
 | 
			
		||||
    {
 | 
			
		||||
      if (!meta_monitor_manager_apply_monitors_config (manager,
 | 
			
		||||
 
 | 
			
		||||
@@ -87,7 +87,11 @@ meta_screen_cast_monitor_stream_src_get_specs (MetaScreenCastStreamSrc *src,
 | 
			
		||||
  logical_monitor = meta_monitor_get_logical_monitor (monitor);
 | 
			
		||||
  mode = meta_monitor_get_current_mode (monitor);
 | 
			
		||||
 | 
			
		||||
  scale = logical_monitor->scale;
 | 
			
		||||
  if (meta_is_stage_views_scaled ())
 | 
			
		||||
    scale = logical_monitor->scale;
 | 
			
		||||
  else
 | 
			
		||||
    scale = 1.0;
 | 
			
		||||
 | 
			
		||||
  *width = (int) roundf (logical_monitor->rect.width * scale);
 | 
			
		||||
  *height = (int) roundf (logical_monitor->rect.height * scale);
 | 
			
		||||
  *frame_rate = meta_monitor_mode_get_refresh_rate (mode);
 | 
			
		||||
 
 | 
			
		||||
@@ -798,6 +798,7 @@ static void
 | 
			
		||||
cursor_priv_free (MetaCursorNativePrivate *cursor_priv)
 | 
			
		||||
{
 | 
			
		||||
  g_hash_table_destroy (cursor_priv->gpu_states);
 | 
			
		||||
  g_free (cursor_priv);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaCursorNativePrivate *
 | 
			
		||||
 
 | 
			
		||||
@@ -3342,6 +3342,7 @@ create_renderer_gpu_data_egl_device (MetaRendererNative  *renderer_native,
 | 
			
		||||
                   G_IO_ERROR_FAILED,
 | 
			
		||||
                   "Missing EGL extensions required for EGLDevice renderer: %s",
 | 
			
		||||
                   missing_extensions_str);
 | 
			
		||||
      meta_egl_terminate (egl, egl_display, NULL);
 | 
			
		||||
      g_free (missing_extensions_str);
 | 
			
		||||
      g_free (missing_extensions);
 | 
			
		||||
      return NULL;
 | 
			
		||||
 
 | 
			
		||||
@@ -60,6 +60,10 @@ struct _MetaBackendX11Private
 | 
			
		||||
  XSyncAlarm user_active_alarm;
 | 
			
		||||
  XSyncCounter counter;
 | 
			
		||||
 | 
			
		||||
  int current_touch_replay_sync_serial;
 | 
			
		||||
  int pending_touch_replay_sync_serial;
 | 
			
		||||
  Atom touch_replay_sync_atom;
 | 
			
		||||
 | 
			
		||||
  int xinput_opcode;
 | 
			
		||||
  int xinput_event_base;
 | 
			
		||||
  int xinput_error_base;
 | 
			
		||||
@@ -168,6 +172,26 @@ meta_backend_x11_translate_device_event (MetaBackendX11 *x11,
 | 
			
		||||
  backend_x11_class->translate_device_event (x11, device_event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
maybe_translate_touch_replay_pointer_event (MetaBackendX11 *x11,
 | 
			
		||||
                                            XIDeviceEvent  *device_event)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
 | 
			
		||||
 | 
			
		||||
  if (!device_event->send_event &&
 | 
			
		||||
      device_event->time != META_CURRENT_TIME &&
 | 
			
		||||
      priv->current_touch_replay_sync_serial !=
 | 
			
		||||
      priv->pending_touch_replay_sync_serial &&
 | 
			
		||||
      XSERVER_TIME_IS_BEFORE (device_event->time, priv->latest_evtime))
 | 
			
		||||
    {
 | 
			
		||||
      /* Emulated pointer events received after XIRejectTouch is received
 | 
			
		||||
       * on a passive touch grab will contain older timestamps, update those
 | 
			
		||||
       * so we dont get InvalidTime at grabs.
 | 
			
		||||
       */
 | 
			
		||||
      device_event->time = priv->latest_evtime;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
translate_device_event (MetaBackendX11 *x11,
 | 
			
		||||
                        XIDeviceEvent  *device_event)
 | 
			
		||||
@@ -177,19 +201,7 @@ translate_device_event (MetaBackendX11 *x11,
 | 
			
		||||
  meta_backend_x11_translate_device_event (x11, device_event);
 | 
			
		||||
 | 
			
		||||
  if (!device_event->send_event && device_event->time != META_CURRENT_TIME)
 | 
			
		||||
    {
 | 
			
		||||
      if (XSERVER_TIME_IS_BEFORE (device_event->time, priv->latest_evtime))
 | 
			
		||||
        {
 | 
			
		||||
          /* Emulated pointer events received after XIRejectTouch is received
 | 
			
		||||
           * on a passive touch grab will contain older timestamps, update those
 | 
			
		||||
           * so we dont get InvalidTime at grabs.
 | 
			
		||||
           */
 | 
			
		||||
          device_event->time = priv->latest_evtime;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      /* Update the internal latest evtime, for any possible later use */
 | 
			
		||||
      priv->latest_evtime = device_event->time;
 | 
			
		||||
    }
 | 
			
		||||
    priv->latest_evtime = device_event->time;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -254,6 +266,9 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
 | 
			
		||||
    case XI_Motion:
 | 
			
		||||
    case XI_ButtonPress:
 | 
			
		||||
    case XI_ButtonRelease:
 | 
			
		||||
      maybe_translate_touch_replay_pointer_event (x11,
 | 
			
		||||
                                                  (XIDeviceEvent *) input_event);
 | 
			
		||||
      /* Intentional fall-through */
 | 
			
		||||
    case XI_KeyPress:
 | 
			
		||||
    case XI_KeyRelease:
 | 
			
		||||
    case XI_TouchBegin:
 | 
			
		||||
@@ -321,6 +336,17 @@ handle_host_xevent (MetaBackend *backend,
 | 
			
		||||
  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
 | 
			
		||||
  gboolean bypass_clutter = FALSE;
 | 
			
		||||
 | 
			
		||||
  switch (event->type)
 | 
			
		||||
    {
 | 
			
		||||
    case ClientMessage:
 | 
			
		||||
      if (event->xclient.window == meta_backend_x11_get_xwindow (x11) &&
 | 
			
		||||
          event->xclient.message_type == priv->touch_replay_sync_atom)
 | 
			
		||||
        priv->current_touch_replay_sync_serial = event->xclient.data.l[0];
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  XGetEventData (priv->xdisplay, &event->xcookie);
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
@@ -528,6 +554,10 @@ meta_backend_x11_post_init (MetaBackend *backend)
 | 
			
		||||
  monitor_manager = meta_backend_get_monitor_manager (backend);
 | 
			
		||||
  g_signal_connect (monitor_manager, "monitors-changed-internal",
 | 
			
		||||
                    G_CALLBACK (on_monitors_changed), backend);
 | 
			
		||||
 | 
			
		||||
  priv->touch_replay_sync_atom = XInternAtom (priv->xdisplay,
 | 
			
		||||
                                              "_MUTTER_TOUCH_SEQUENCE_SYNC",
 | 
			
		||||
                                              False);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ClutterBackend *
 | 
			
		||||
@@ -584,6 +614,43 @@ meta_backend_x11_ungrab_device (MetaBackend *backend,
 | 
			
		||||
  return (ret == Success);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_backend_x11_finish_touch_sequence (MetaBackend          *backend,
 | 
			
		||||
                                        ClutterEventSequence *sequence,
 | 
			
		||||
                                        MetaSequenceState     state)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
 | 
			
		||||
  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
 | 
			
		||||
  int event_mode;
 | 
			
		||||
 | 
			
		||||
  if (state == META_SEQUENCE_ACCEPTED)
 | 
			
		||||
    event_mode = XIAcceptTouch;
 | 
			
		||||
  else if (state == META_SEQUENCE_REJECTED)
 | 
			
		||||
    event_mode = XIRejectTouch;
 | 
			
		||||
  else
 | 
			
		||||
    g_return_if_reached ();
 | 
			
		||||
 | 
			
		||||
  XIAllowTouchEvents (priv->xdisplay,
 | 
			
		||||
                      META_VIRTUAL_CORE_POINTER_ID,
 | 
			
		||||
                      clutter_x11_event_sequence_get_touch_detail (sequence),
 | 
			
		||||
                      DefaultRootWindow (priv->xdisplay), event_mode);
 | 
			
		||||
 | 
			
		||||
  if (state == META_SEQUENCE_REJECTED)
 | 
			
		||||
    {
 | 
			
		||||
      XClientMessageEvent ev;
 | 
			
		||||
 | 
			
		||||
      ev = (XClientMessageEvent) {
 | 
			
		||||
        .type = ClientMessage,
 | 
			
		||||
        .window = meta_backend_x11_get_xwindow (x11),
 | 
			
		||||
        .message_type = priv->touch_replay_sync_atom,
 | 
			
		||||
        .format = 32,
 | 
			
		||||
        .data.l[0] = ++priv->pending_touch_replay_sync_serial,
 | 
			
		||||
      };
 | 
			
		||||
      XSendEvent (priv->xdisplay, meta_backend_x11_get_xwindow (x11),
 | 
			
		||||
                  False, 0, (XEvent *) &ev);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_backend_x11_warp_pointer (MetaBackend *backend,
 | 
			
		||||
                               int          x,
 | 
			
		||||
@@ -769,6 +836,7 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
 | 
			
		||||
  backend_class->post_init = meta_backend_x11_post_init;
 | 
			
		||||
  backend_class->grab_device = meta_backend_x11_grab_device;
 | 
			
		||||
  backend_class->ungrab_device = meta_backend_x11_ungrab_device;
 | 
			
		||||
  backend_class->finish_touch_sequence = meta_backend_x11_finish_touch_sequence;
 | 
			
		||||
  backend_class->warp_pointer = meta_backend_x11_warp_pointer;
 | 
			
		||||
  backend_class->get_current_logical_monitor = meta_backend_x11_get_current_logical_monitor;
 | 
			
		||||
  backend_class->get_keymap = meta_backend_x11_get_keymap;
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,9 @@ struct _MetaCompositor
 | 
			
		||||
  guint           pre_paint_func_id;
 | 
			
		||||
  guint           post_paint_func_id;
 | 
			
		||||
 | 
			
		||||
  guint           stage_presented_id;
 | 
			
		||||
  guint           stage_after_paint_id;
 | 
			
		||||
 | 
			
		||||
  gint64          server_time_query_time;
 | 
			
		||||
  gint64          server_time_offset;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -91,6 +91,10 @@ on_presented (ClutterStage     *stage,
 | 
			
		||||
              ClutterFrameInfo *frame_info,
 | 
			
		||||
              MetaCompositor   *compositor);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_top_window_actor_destroyed (MetaWindowActor *window_actor,
 | 
			
		||||
                               MetaCompositor  *compositor);
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
is_modal (MetaDisplay *display)
 | 
			
		||||
{
 | 
			
		||||
@@ -130,9 +134,31 @@ meta_switch_workspace_completed (MetaCompositor *compositor)
 | 
			
		||||
void
 | 
			
		||||
meta_compositor_destroy (MetaCompositor *compositor)
 | 
			
		||||
{
 | 
			
		||||
  g_signal_handler_disconnect (compositor->stage,
 | 
			
		||||
                               compositor->stage_after_paint_id);
 | 
			
		||||
  g_signal_handler_disconnect (compositor->stage,
 | 
			
		||||
                               compositor->stage_presented_id);
 | 
			
		||||
 | 
			
		||||
  compositor->stage_after_paint_id = 0;
 | 
			
		||||
  compositor->stage_presented_id = 0;
 | 
			
		||||
  compositor->stage = NULL;
 | 
			
		||||
 | 
			
		||||
  clutter_threads_remove_repaint_func (compositor->pre_paint_func_id);
 | 
			
		||||
  clutter_threads_remove_repaint_func (compositor->post_paint_func_id);
 | 
			
		||||
 | 
			
		||||
  if (compositor->top_window_actor)
 | 
			
		||||
    {
 | 
			
		||||
      g_signal_handlers_disconnect_by_func (compositor->top_window_actor,
 | 
			
		||||
                                            on_top_window_actor_destroyed,
 | 
			
		||||
                                            compositor);
 | 
			
		||||
      compositor->top_window_actor = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&compositor->window_group, clutter_actor_destroy);
 | 
			
		||||
  g_clear_pointer (&compositor->top_window_group, clutter_actor_destroy);
 | 
			
		||||
  g_clear_pointer (&compositor->feedback_group, clutter_actor_destroy);
 | 
			
		||||
  g_clear_pointer (&compositor->windows, g_list_free);
 | 
			
		||||
 | 
			
		||||
  if (compositor->have_x11_sync_object)
 | 
			
		||||
    meta_sync_ring_destroy ();
 | 
			
		||||
}
 | 
			
		||||
@@ -502,9 +528,10 @@ meta_compositor_manage (MetaCompositor *compositor)
 | 
			
		||||
 | 
			
		||||
  compositor->stage = meta_backend_get_stage (backend);
 | 
			
		||||
 | 
			
		||||
  g_signal_connect (compositor->stage, "presented",
 | 
			
		||||
                    G_CALLBACK (on_presented),
 | 
			
		||||
                    compositor);
 | 
			
		||||
  compositor->stage_presented_id =
 | 
			
		||||
    g_signal_connect (compositor->stage, "presented",
 | 
			
		||||
                      G_CALLBACK (on_presented),
 | 
			
		||||
                                                     compositor);
 | 
			
		||||
 | 
			
		||||
  /* We use connect_after() here to accomodate code in GNOME Shell that,
 | 
			
		||||
   * when benchmarking drawing performance, connects to ::after-paint
 | 
			
		||||
@@ -514,8 +541,9 @@ meta_compositor_manage (MetaCompositor *compositor)
 | 
			
		||||
   * connections to ::after-paint, connect() vs. connect_after() doesn't
 | 
			
		||||
   * matter.
 | 
			
		||||
   */
 | 
			
		||||
  g_signal_connect_after (CLUTTER_STAGE (compositor->stage), "after-paint",
 | 
			
		||||
                          G_CALLBACK (after_stage_paint), compositor);
 | 
			
		||||
  compositor->stage_after_paint_id =
 | 
			
		||||
    g_signal_connect_after (compositor->stage, "after-paint",
 | 
			
		||||
                            G_CALLBACK (after_stage_paint), compositor);
 | 
			
		||||
 | 
			
		||||
  clutter_stage_set_sync_delay (CLUTTER_STAGE (compositor->stage), META_SYNC_DELAY);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,7 @@
 | 
			
		||||
#include <meta/meta-x11-errors.h>
 | 
			
		||||
#include "window-private.h"
 | 
			
		||||
#include "meta-shaped-texture-private.h"
 | 
			
		||||
#include "meta-window-actor-private.h"
 | 
			
		||||
#include "meta-cullable.h"
 | 
			
		||||
#include "x11/window-x11.h"
 | 
			
		||||
#include "x11/meta-x11-display-private.h"
 | 
			
		||||
@@ -69,11 +70,13 @@ free_damage (MetaSurfaceActorX11 *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
 | 
			
		||||
  MetaDisplay *display = priv->display;
 | 
			
		||||
  Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
 | 
			
		||||
  Display *xdisplay;
 | 
			
		||||
 | 
			
		||||
  if (priv->damage == None)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
 | 
			
		||||
 | 
			
		||||
  meta_x11_error_trap_push (display->x11_display);
 | 
			
		||||
  XDamageDestroy (xdisplay, priv->damage);
 | 
			
		||||
  priv->damage = None;
 | 
			
		||||
@@ -85,12 +88,14 @@ detach_pixmap (MetaSurfaceActorX11 *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
 | 
			
		||||
  MetaDisplay *display = priv->display;
 | 
			
		||||
  Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
 | 
			
		||||
  MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
 | 
			
		||||
  Display *xdisplay;
 | 
			
		||||
 | 
			
		||||
  if (priv->pixmap == None)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
 | 
			
		||||
 | 
			
		||||
  /* Get rid of all references to the pixmap before freeing it; it's unclear whether
 | 
			
		||||
   * you are supposed to be able to free a GLXPixmap after freeing the underlying
 | 
			
		||||
   * pixmap, but it certainly doesn't work with current DRI/Mesa
 | 
			
		||||
@@ -353,13 +358,19 @@ meta_surface_actor_x11_is_unredirected (MetaSurfaceActor *actor)
 | 
			
		||||
  return priv->unredirected;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
release_x11_resources (MetaSurfaceActorX11 *self)
 | 
			
		||||
{
 | 
			
		||||
  detach_pixmap (self);
 | 
			
		||||
  free_damage (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_surface_actor_x11_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (object);
 | 
			
		||||
 | 
			
		||||
  detach_pixmap (self);
 | 
			
		||||
  free_damage (self);
 | 
			
		||||
  release_x11_resources (self);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (meta_surface_actor_x11_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
@@ -417,8 +428,7 @@ window_decorated_notify (MetaWindow *window,
 | 
			
		||||
{
 | 
			
		||||
  MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (user_data);
 | 
			
		||||
 | 
			
		||||
  detach_pixmap (self);
 | 
			
		||||
  free_damage (self);
 | 
			
		||||
  release_x11_resources (self);
 | 
			
		||||
  create_damage (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -457,6 +467,10 @@ meta_surface_actor_x11_new (MetaWindow *window)
 | 
			
		||||
  g_signal_connect_object (priv->window, "notify::decorated",
 | 
			
		||||
                           G_CALLBACK (window_decorated_notify), self, 0);
 | 
			
		||||
 | 
			
		||||
  g_signal_connect_object (meta_window_actor_from_window (window), "destroy",
 | 
			
		||||
                           G_CALLBACK (release_x11_resources), self,
 | 
			
		||||
                           G_CONNECT_SWAPPED);
 | 
			
		||||
 | 
			
		||||
  priv->unredirected = FALSE;
 | 
			
		||||
  sync_unredirected (self);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -471,6 +471,9 @@ meta_window_actor_constructed (GObject *object)
 | 
			
		||||
 | 
			
		||||
  priv->compositor = window->display->compositor;
 | 
			
		||||
 | 
			
		||||
  /* Hang our compositor window state off the MetaWindow for fast retrieval */
 | 
			
		||||
  meta_window_set_compositor_private (window, object);
 | 
			
		||||
 | 
			
		||||
  meta_window_actor_update_surface (self);
 | 
			
		||||
 | 
			
		||||
  meta_window_actor_update_opacity (self);
 | 
			
		||||
@@ -1448,9 +1451,6 @@ meta_window_actor_new (MetaWindow *window)
 | 
			
		||||
 | 
			
		||||
  meta_window_actor_sync_actor_geometry (self, priv->window->placed);
 | 
			
		||||
 | 
			
		||||
  /* Hang our compositor window state off the MetaWindow for fast retrieval */
 | 
			
		||||
  meta_window_set_compositor_private (window, G_OBJECT (self));
 | 
			
		||||
 | 
			
		||||
  if (window->layer == META_LAYER_OVERRIDE_REDIRECT)
 | 
			
		||||
    window_group = compositor->top_window_group;
 | 
			
		||||
  else
 | 
			
		||||
 
 | 
			
		||||
@@ -57,6 +57,7 @@
 | 
			
		||||
#include "backends/native/meta-backend-native.h"
 | 
			
		||||
#include "backends/x11/meta-backend-x11.h"
 | 
			
		||||
#include "backends/meta-stage-private.h"
 | 
			
		||||
#include "backends/meta-backend-private.h"
 | 
			
		||||
#include "backends/meta-input-settings-private.h"
 | 
			
		||||
#include <clutter/x11/clutter-x11.h>
 | 
			
		||||
 | 
			
		||||
@@ -602,27 +603,23 @@ gesture_tracker_state_changed (MetaGestureTracker   *tracker,
 | 
			
		||||
                               MetaSequenceState     state,
 | 
			
		||||
                               MetaDisplay          *display)
 | 
			
		||||
{
 | 
			
		||||
  if (meta_is_wayland_compositor ())
 | 
			
		||||
  switch (state)
 | 
			
		||||
    {
 | 
			
		||||
      if (state == META_SEQUENCE_ACCEPTED)
 | 
			
		||||
        meta_display_cancel_touch (display);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
 | 
			
		||||
      int event_mode;
 | 
			
		||||
    case META_SEQUENCE_NONE:
 | 
			
		||||
    case META_SEQUENCE_PENDING_END:
 | 
			
		||||
      return;
 | 
			
		||||
    case META_SEQUENCE_ACCEPTED:
 | 
			
		||||
      meta_display_cancel_touch (display);
 | 
			
		||||
 | 
			
		||||
      if (state == META_SEQUENCE_ACCEPTED)
 | 
			
		||||
        event_mode = XIAcceptTouch;
 | 
			
		||||
      else if (state == META_SEQUENCE_REJECTED)
 | 
			
		||||
        event_mode = XIRejectTouch;
 | 
			
		||||
      else
 | 
			
		||||
        return;
 | 
			
		||||
      /* Intentional fall-through */
 | 
			
		||||
    case META_SEQUENCE_REJECTED:
 | 
			
		||||
      {
 | 
			
		||||
        MetaBackend *backend;
 | 
			
		||||
 | 
			
		||||
      XIAllowTouchEvents (meta_backend_x11_get_xdisplay (backend),
 | 
			
		||||
                          META_VIRTUAL_CORE_POINTER_ID,
 | 
			
		||||
                          clutter_x11_event_sequence_get_touch_detail (sequence),
 | 
			
		||||
                          DefaultRootWindow (display->x11_display->xdisplay), event_mode);
 | 
			
		||||
        backend = meta_get_backend ();
 | 
			
		||||
        meta_backend_finish_touch_sequence (backend, sequence, state);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,8 @@
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include <meta/window.h>
 | 
			
		||||
 | 
			
		||||
#include "backends/meta-backend-private.h"
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_GESTURE_TRACKER            (meta_gesture_tracker_get_type ())
 | 
			
		||||
#define META_GESTURE_TRACKER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_GESTURE_TRACKER, MetaGestureTracker))
 | 
			
		||||
#define META_GESTURE_TRACKER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_GESTURE_TRACKER, MetaGestureTrackerClass))
 | 
			
		||||
@@ -38,13 +40,6 @@
 | 
			
		||||
typedef struct _MetaGestureTracker MetaGestureTracker;
 | 
			
		||||
typedef struct _MetaGestureTrackerClass MetaGestureTrackerClass;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  META_SEQUENCE_NONE,
 | 
			
		||||
  META_SEQUENCE_ACCEPTED,
 | 
			
		||||
  META_SEQUENCE_REJECTED,
 | 
			
		||||
  META_SEQUENCE_PENDING_END
 | 
			
		||||
} MetaSequenceState;
 | 
			
		||||
 | 
			
		||||
struct _MetaGestureTracker
 | 
			
		||||
{
 | 
			
		||||
  GObject parent_instance;
 | 
			
		||||
 
 | 
			
		||||
@@ -1183,6 +1183,27 @@ window_contains_point (MetaWindow *window,
 | 
			
		||||
  return POINT_IN_RECT (root_x, root_y, rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
window_can_get_default_focus (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  if (window->unmaps_pending > 0)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (window->unmanaging)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (!(window->input || window->take_focus))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (!meta_window_should_be_showing (window))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (window->type == META_WINDOW_DOCK)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaWindow*
 | 
			
		||||
get_default_focus_window (MetaStack     *stack,
 | 
			
		||||
                          MetaWorkspace *workspace,
 | 
			
		||||
@@ -1210,24 +1231,12 @@ get_default_focus_window (MetaStack     *stack,
 | 
			
		||||
      if (window == not_this_one)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (window->unmaps_pending > 0)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (window->unmanaging)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (!(window->input || window->take_focus))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (!meta_window_should_be_showing (window))
 | 
			
		||||
      if (!window_can_get_default_focus (window))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (must_be_at_point && !window_contains_point (window, root_x, root_y))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (window->type == META_WINDOW_DOCK)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      return window;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1282,6 +1291,26 @@ meta_stack_list_windows (MetaStack     *stack,
 | 
			
		||||
  return workspace_windows;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GList *
 | 
			
		||||
meta_stack_get_default_focus_candidates (MetaStack     *stack,
 | 
			
		||||
                                         MetaWorkspace *workspace)
 | 
			
		||||
{
 | 
			
		||||
  GList *windows = meta_stack_list_windows (stack, workspace);
 | 
			
		||||
  GList *l;
 | 
			
		||||
 | 
			
		||||
  for (l = windows; l;)
 | 
			
		||||
    {
 | 
			
		||||
      GList *next = l->next;
 | 
			
		||||
 | 
			
		||||
      if (!window_can_get_default_focus (l->data))
 | 
			
		||||
        windows = g_list_delete_link (windows, l);
 | 
			
		||||
 | 
			
		||||
      l = next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return windows;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
meta_stack_windows_cmp  (MetaStack  *stack,
 | 
			
		||||
                         MetaWindow *window_a,
 | 
			
		||||
 
 | 
			
		||||
@@ -337,6 +337,21 @@ MetaWindow* meta_stack_get_default_focus_window_at_point (MetaStack     *stack,
 | 
			
		||||
                                                          int            root_x,
 | 
			
		||||
                                                          int            root_y);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_stack_get_default_focus_candidates:
 | 
			
		||||
 * @stack: The stack to examine.
 | 
			
		||||
 * @workspace: If not %NULL, only windows on this workspace will be
 | 
			
		||||
 *             returned; otherwise all windows in the stack will be
 | 
			
		||||
 *             returned.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns all the focus candidate windows in the stack, in order.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer container) (element-type Meta.Window):
 | 
			
		||||
 *     A #GList of #MetaWindow, in stacking order, honouring layers.
 | 
			
		||||
 */
 | 
			
		||||
GList *     meta_stack_get_default_focus_candidates (MetaStack     *stack,
 | 
			
		||||
                                                     MetaWorkspace *workspace);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_stack_list_windows:
 | 
			
		||||
 * @stack: The stack to examine.
 | 
			
		||||
 
 | 
			
		||||
@@ -82,6 +82,7 @@ typedef enum
 | 
			
		||||
  META_MOVE_RESIZE_UNMAXIMIZE = 1 << 6,
 | 
			
		||||
  META_MOVE_RESIZE_FORCE_MOVE = 1 << 7,
 | 
			
		||||
  META_MOVE_RESIZE_WAYLAND_STATE_CHANGED = 1 << 8,
 | 
			
		||||
  META_MOVE_RESIZE_FORCE_UPDATE_MONITOR = 1 << 9,
 | 
			
		||||
} MetaMoveResizeFlags;
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
 
 | 
			
		||||
@@ -121,6 +121,7 @@ static gboolean queue_calc_showing_func (MetaWindow *window,
 | 
			
		||||
                                         void       *data);
 | 
			
		||||
 | 
			
		||||
static void meta_window_move_between_rects (MetaWindow          *window,
 | 
			
		||||
                                            MetaMoveResizeFlags  move_resize_flags,
 | 
			
		||||
                                            const MetaRectangle *old_area,
 | 
			
		||||
                                            const MetaRectangle *new_area);
 | 
			
		||||
 | 
			
		||||
@@ -3638,6 +3639,13 @@ meta_window_activate_full (MetaWindow     *window,
 | 
			
		||||
{
 | 
			
		||||
  MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
 | 
			
		||||
  gboolean allow_workspace_switch;
 | 
			
		||||
 | 
			
		||||
  if (window->unmanaging)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Trying to activate unmanaged window '%s'", window->desc);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_topic (META_DEBUG_FOCUS,
 | 
			
		||||
              "_NET_ACTIVE_WINDOW message sent for %s at time %u "
 | 
			
		||||
              "by client type %u.\n",
 | 
			
		||||
@@ -3865,6 +3873,7 @@ meta_window_update_for_monitors_changed (MetaWindow *window)
 | 
			
		||||
       * monitors changed and the same index could be refereing
 | 
			
		||||
       * to a different monitor. */
 | 
			
		||||
      meta_window_move_between_rects (window,
 | 
			
		||||
                                      META_MOVE_RESIZE_FORCE_UPDATE_MONITOR,
 | 
			
		||||
                                      &old->rect,
 | 
			
		||||
                                      &new->rect);
 | 
			
		||||
    }
 | 
			
		||||
@@ -4046,6 +4055,8 @@ meta_window_move_resize_internal (MetaWindow          *window,
 | 
			
		||||
  update_monitor_flags = META_WINDOW_UPDATE_MONITOR_FLAGS_NONE;
 | 
			
		||||
  if (flags & META_MOVE_RESIZE_USER_ACTION)
 | 
			
		||||
    update_monitor_flags |= META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP;
 | 
			
		||||
  if (flags & META_MOVE_RESIZE_FORCE_UPDATE_MONITOR)
 | 
			
		||||
    update_monitor_flags |= META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE;
 | 
			
		||||
 | 
			
		||||
  if (window->monitor)
 | 
			
		||||
    {
 | 
			
		||||
@@ -4105,6 +4116,7 @@ meta_window_move_frame (MetaWindow *window,
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_move_between_rects (MetaWindow  *window,
 | 
			
		||||
                                MetaMoveResizeFlags  move_resize_flags,
 | 
			
		||||
                                const MetaRectangle *old_area,
 | 
			
		||||
                                const MetaRectangle *new_area)
 | 
			
		||||
{
 | 
			
		||||
@@ -4128,7 +4140,12 @@ meta_window_move_between_rects (MetaWindow  *window,
 | 
			
		||||
  window->saved_rect.x = window->unconstrained_rect.x;
 | 
			
		||||
  window->saved_rect.y = window->unconstrained_rect.y;
 | 
			
		||||
 | 
			
		||||
  meta_window_move_resize_now (window);
 | 
			
		||||
  meta_window_move_resize_internal (window,
 | 
			
		||||
                                    move_resize_flags |
 | 
			
		||||
                                    META_MOVE_RESIZE_MOVE_ACTION |
 | 
			
		||||
                                    META_MOVE_RESIZE_RESIZE_ACTION,
 | 
			
		||||
                                    NorthWestGravity,
 | 
			
		||||
                                    window->unconstrained_rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -4189,14 +4206,14 @@ meta_window_move_to_monitor (MetaWindow  *window,
 | 
			
		||||
      window->unconstrained_rect.height == 0 ||
 | 
			
		||||
      !meta_rectangle_overlap (&window->unconstrained_rect, &old_area))
 | 
			
		||||
    {
 | 
			
		||||
      meta_window_move_between_rects (window, NULL, &new_area);
 | 
			
		||||
      meta_window_move_between_rects (window, 0, NULL, &new_area);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      if (monitor == window->monitor->number)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
      meta_window_move_between_rects (window, &old_area, &new_area);
 | 
			
		||||
      meta_window_move_between_rects (window, 0, &old_area, &new_area);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  window->preferred_output_winsys_id = window->monitor->winsys_id;
 | 
			
		||||
 
 | 
			
		||||
@@ -86,6 +86,12 @@ typedef struct _MetaWorkspaceLogicalMonitorData
 | 
			
		||||
  MetaRectangle logical_monitor_work_area;
 | 
			
		||||
} MetaWorkspaceLogicalMonitorData;
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaWorkspaceFocusableAncestorData
 | 
			
		||||
{
 | 
			
		||||
  MetaWorkspace *workspace;
 | 
			
		||||
  MetaWindow *out_window;
 | 
			
		||||
} MetaWorkspaceFocusableAncestorData;
 | 
			
		||||
 | 
			
		||||
static MetaWorkspaceLogicalMonitorData *
 | 
			
		||||
meta_workspace_get_logical_monitor_data (MetaWorkspace      *workspace,
 | 
			
		||||
                                         MetaLogicalMonitor *logical_monitor)
 | 
			
		||||
@@ -1327,13 +1333,20 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
record_ancestor (MetaWindow *window,
 | 
			
		||||
                 void       *data)
 | 
			
		||||
find_focusable_ancestor (MetaWindow *window,
 | 
			
		||||
                         gpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindow **result = data;
 | 
			
		||||
  MetaWorkspaceFocusableAncestorData *data = user_data;
 | 
			
		||||
 | 
			
		||||
  *result = window;
 | 
			
		||||
  return FALSE; /* quit with the first ancestor we find */
 | 
			
		||||
  if (!window->unmanaging && (window->input || window->take_focus) &&
 | 
			
		||||
      meta_window_located_on_workspace (window, data->workspace) &&
 | 
			
		||||
      meta_window_showing_on_its_workspace (window))
 | 
			
		||||
    {
 | 
			
		||||
      data->out_window = window;
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Focus ancestor of not_this_one if there is one */
 | 
			
		||||
@@ -1355,11 +1368,15 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
 | 
			
		||||
  if (not_this_one)
 | 
			
		||||
    {
 | 
			
		||||
      MetaWindow *ancestor;
 | 
			
		||||
      ancestor = NULL;
 | 
			
		||||
      meta_window_foreach_ancestor (not_this_one, record_ancestor, &ancestor);
 | 
			
		||||
      if (ancestor != NULL &&
 | 
			
		||||
          meta_window_located_on_workspace (ancestor, workspace) &&
 | 
			
		||||
          meta_window_showing_on_its_workspace (ancestor))
 | 
			
		||||
      MetaWorkspaceFocusableAncestorData data;
 | 
			
		||||
 | 
			
		||||
      data = (MetaWorkspaceFocusableAncestorData) {
 | 
			
		||||
        .workspace = workspace,
 | 
			
		||||
      };
 | 
			
		||||
      meta_window_foreach_ancestor (not_this_one, find_focusable_ancestor, &data);
 | 
			
		||||
      ancestor = data.out_window;
 | 
			
		||||
 | 
			
		||||
      if (ancestor)
 | 
			
		||||
        {
 | 
			
		||||
          meta_topic (META_DEBUG_FOCUS,
 | 
			
		||||
                      "Focusing %s, ancestor of %s\n",
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,23 @@
 | 
			
		||||
new_client 1 x11
 | 
			
		||||
create 1/1
 | 
			
		||||
show 1/1
 | 
			
		||||
 | 
			
		||||
create 1/2 csd
 | 
			
		||||
set_parent 1/2 1
 | 
			
		||||
can_take_focus 1/2 false
 | 
			
		||||
accept_focus 1/2 false
 | 
			
		||||
show 1/2
 | 
			
		||||
 | 
			
		||||
create 1/3 csd
 | 
			
		||||
set_parent 1/3 2
 | 
			
		||||
show 1/3
 | 
			
		||||
 | 
			
		||||
wait
 | 
			
		||||
assert_focused 1/3
 | 
			
		||||
assert_stacking 1/1 1/2 1/3
 | 
			
		||||
 | 
			
		||||
destroy 1/3
 | 
			
		||||
 | 
			
		||||
wait
 | 
			
		||||
assert_focused 1/1
 | 
			
		||||
assert_stacking 1/1 1/2
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
new_client 2 x11
 | 
			
		||||
create 2/1
 | 
			
		||||
show 2/1
 | 
			
		||||
wait
 | 
			
		||||
 | 
			
		||||
new_client 1 x11
 | 
			
		||||
create 1/1
 | 
			
		||||
accept_focus 1/1 false
 | 
			
		||||
can_take_focus 1/1 false
 | 
			
		||||
show 1/1
 | 
			
		||||
 | 
			
		||||
create 1/2 csd
 | 
			
		||||
set_parent 1/2 1
 | 
			
		||||
can_take_focus 1/2 false
 | 
			
		||||
accept_focus 1/2 false
 | 
			
		||||
show 1/2
 | 
			
		||||
 | 
			
		||||
create 1/3 csd
 | 
			
		||||
set_parent 1/3 2
 | 
			
		||||
show 1/3
 | 
			
		||||
 | 
			
		||||
wait
 | 
			
		||||
assert_focused 1/3
 | 
			
		||||
assert_stacking 2/1 1/1 1/2 1/3
 | 
			
		||||
 | 
			
		||||
destroy 1/3
 | 
			
		||||
 | 
			
		||||
wait
 | 
			
		||||
assert_stacking 1/1 1/2 2/1
 | 
			
		||||
assert_focused 2/1
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
new_client 2 x11
 | 
			
		||||
create 2/1
 | 
			
		||||
show 2/1
 | 
			
		||||
 | 
			
		||||
new_client 1 x11
 | 
			
		||||
create 1/1
 | 
			
		||||
show 1/1
 | 
			
		||||
 | 
			
		||||
create 1/2 csd
 | 
			
		||||
set_parent 1/2 1
 | 
			
		||||
accept_focus 1/2 false
 | 
			
		||||
show 1/2
 | 
			
		||||
 | 
			
		||||
create 1/3 csd
 | 
			
		||||
set_parent 1/3 2
 | 
			
		||||
show 1/3
 | 
			
		||||
 | 
			
		||||
wait
 | 
			
		||||
assert_focused 1/3
 | 
			
		||||
assert_stacking 2/1 1/1 1/2 1/3
 | 
			
		||||
 | 
			
		||||
destroy 1/3
 | 
			
		||||
sleep 10
 | 
			
		||||
 | 
			
		||||
assert_focused none
 | 
			
		||||
assert_stacking 2/1 1/1 1/2
 | 
			
		||||
 | 
			
		||||
activate 2/1
 | 
			
		||||
wait
 | 
			
		||||
 | 
			
		||||
assert_focused 2/1
 | 
			
		||||
assert_stacking 1/1 1/2 2/1
 | 
			
		||||
 | 
			
		||||
sleep 250
 | 
			
		||||
assert_focused 2/1
 | 
			
		||||
assert_stacking 1/1 1/2 2/1
 | 
			
		||||
							
								
								
									
										30
									
								
								src/tests/stacking/closed-transient-no-input-parent.metatest
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/tests/stacking/closed-transient-no-input-parent.metatest
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
new_client 2 x11
 | 
			
		||||
create 2/1
 | 
			
		||||
show 2/1
 | 
			
		||||
 | 
			
		||||
new_client 1 x11
 | 
			
		||||
create 1/1
 | 
			
		||||
show 1/1
 | 
			
		||||
 | 
			
		||||
create 1/2 csd
 | 
			
		||||
set_parent 1/2 1
 | 
			
		||||
accept_focus 1/2 false
 | 
			
		||||
show 1/2
 | 
			
		||||
 | 
			
		||||
create 1/3 csd
 | 
			
		||||
set_parent 1/3 2
 | 
			
		||||
show 1/3
 | 
			
		||||
 | 
			
		||||
wait
 | 
			
		||||
assert_focused 1/3
 | 
			
		||||
assert_stacking 2/1 1/1 1/2 1/3
 | 
			
		||||
 | 
			
		||||
destroy 1/3
 | 
			
		||||
dispatch
 | 
			
		||||
 | 
			
		||||
assert_focused none
 | 
			
		||||
assert_stacking 2/1 1/1 1/2
 | 
			
		||||
 | 
			
		||||
sleep 150
 | 
			
		||||
assert_focused 1/1
 | 
			
		||||
assert_stacking 2/1 1/1 1/2
 | 
			
		||||
@@ -0,0 +1,43 @@
 | 
			
		||||
new_client 0 x11
 | 
			
		||||
create 0/1
 | 
			
		||||
show 0/1
 | 
			
		||||
 | 
			
		||||
new_client 1 x11
 | 
			
		||||
create 1/1
 | 
			
		||||
show 1/1
 | 
			
		||||
 | 
			
		||||
create 1/2 csd
 | 
			
		||||
set_parent 1/2 1
 | 
			
		||||
accept_focus 1/2 false
 | 
			
		||||
show 1/2
 | 
			
		||||
 | 
			
		||||
create 1/3 csd
 | 
			
		||||
set_parent 1/3 2
 | 
			
		||||
accept_focus 1/3 false
 | 
			
		||||
show 1/3
 | 
			
		||||
 | 
			
		||||
create 1/4 csd
 | 
			
		||||
set_parent 1/4 3
 | 
			
		||||
accept_focus 1/4 false
 | 
			
		||||
show 1/4
 | 
			
		||||
 | 
			
		||||
create 1/5 csd
 | 
			
		||||
set_parent 1/5 3
 | 
			
		||||
show 1/5
 | 
			
		||||
 | 
			
		||||
wait
 | 
			
		||||
assert_focused 1/5
 | 
			
		||||
assert_stacking 0/1 1/1 1/2 1/3 1/4 1/5
 | 
			
		||||
 | 
			
		||||
destroy 1/5
 | 
			
		||||
dispatch
 | 
			
		||||
 | 
			
		||||
assert_focused none
 | 
			
		||||
assert_stacking 0/1 1/1 1/2 1/3 1/4
 | 
			
		||||
 | 
			
		||||
destroy 1/2
 | 
			
		||||
dispatch
 | 
			
		||||
 | 
			
		||||
sleep 450
 | 
			
		||||
assert_focused 1/1
 | 
			
		||||
assert_stacking 0/1 1/1 1/3 1/4
 | 
			
		||||
@@ -0,0 +1,46 @@
 | 
			
		||||
new_client 0 x11
 | 
			
		||||
create 0/1
 | 
			
		||||
show 0/1
 | 
			
		||||
 | 
			
		||||
new_client 1 x11
 | 
			
		||||
create 1/1
 | 
			
		||||
show 1/1
 | 
			
		||||
 | 
			
		||||
create 1/2 csd
 | 
			
		||||
set_parent 1/2 1
 | 
			
		||||
accept_focus 1/2 false
 | 
			
		||||
show 1/2
 | 
			
		||||
 | 
			
		||||
create 1/3 csd
 | 
			
		||||
set_parent 1/3 2
 | 
			
		||||
accept_focus 1/3 false
 | 
			
		||||
show 1/3
 | 
			
		||||
 | 
			
		||||
create 1/4 csd
 | 
			
		||||
set_parent 1/4 3
 | 
			
		||||
accept_focus 1/4 false
 | 
			
		||||
show 1/4
 | 
			
		||||
 | 
			
		||||
create 1/5 csd
 | 
			
		||||
set_parent 1/5 3
 | 
			
		||||
show 1/5
 | 
			
		||||
 | 
			
		||||
wait
 | 
			
		||||
assert_focused 1/5
 | 
			
		||||
assert_stacking 0/1 1/1 1/2 1/3 1/4 1/5
 | 
			
		||||
 | 
			
		||||
destroy 1/5
 | 
			
		||||
dispatch
 | 
			
		||||
 | 
			
		||||
assert_focused none
 | 
			
		||||
assert_stacking 0/1 1/1 1/2 1/3 1/4
 | 
			
		||||
 | 
			
		||||
sleep 600
 | 
			
		||||
assert_focused 1/1
 | 
			
		||||
assert_stacking 0/1 1/1 1/2 1/3 1/4
 | 
			
		||||
 | 
			
		||||
destroy 1/3
 | 
			
		||||
wait
 | 
			
		||||
 | 
			
		||||
assert_focused 1/1
 | 
			
		||||
assert_stacking 0/1 1/1 1/2 1/4
 | 
			
		||||
@@ -0,0 +1,34 @@
 | 
			
		||||
new_client 0 x11
 | 
			
		||||
create 0/1
 | 
			
		||||
show 0/1
 | 
			
		||||
 | 
			
		||||
new_client 1 x11
 | 
			
		||||
create 1/1
 | 
			
		||||
accept_focus 1/1 false
 | 
			
		||||
can_take_focus 1/1 true
 | 
			
		||||
accept_take_focus 1/1 true
 | 
			
		||||
show 1/1
 | 
			
		||||
 | 
			
		||||
create 1/2 csd
 | 
			
		||||
set_parent 1/2 1
 | 
			
		||||
accept_focus 1/2 false
 | 
			
		||||
can_take_focus 1/2 true
 | 
			
		||||
accept_take_focus 1/2 true
 | 
			
		||||
show 1/2
 | 
			
		||||
 | 
			
		||||
create 1/3
 | 
			
		||||
set_parent 1/3 2
 | 
			
		||||
show 1/3
 | 
			
		||||
 | 
			
		||||
assert_focused 1/3
 | 
			
		||||
assert_stacking 0/1 1/1 1/2 1/3
 | 
			
		||||
 | 
			
		||||
destroy 1/3
 | 
			
		||||
wait
 | 
			
		||||
 | 
			
		||||
assert_focused 1/2
 | 
			
		||||
assert_stacking 0/1 1/1 1/2
 | 
			
		||||
 | 
			
		||||
sleep 150
 | 
			
		||||
assert_focused 1/2
 | 
			
		||||
assert_stacking 0/1 1/1 1/2
 | 
			
		||||
@@ -29,6 +29,11 @@
 | 
			
		||||
const char *client_id = "0";
 | 
			
		||||
static gboolean wayland;
 | 
			
		||||
GHashTable *windows;
 | 
			
		||||
GQuark event_source_quark;
 | 
			
		||||
GQuark event_handlers_quark;
 | 
			
		||||
GQuark can_take_focus_quark;
 | 
			
		||||
 | 
			
		||||
typedef void (*XEventHandler) (GtkWidget *window, XEvent *event);
 | 
			
		||||
 | 
			
		||||
static void read_next_line (GDataInputStream *in);
 | 
			
		||||
 | 
			
		||||
@@ -55,6 +60,186 @@ lookup_window (const char *window_id)
 | 
			
		||||
  return window;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  GSource base;
 | 
			
		||||
  GSource **self_ref;
 | 
			
		||||
  GPollFD event_poll_fd;
 | 
			
		||||
  Display *xdisplay;
 | 
			
		||||
} XClientEventSource;
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
x_event_source_prepare (GSource *source,
 | 
			
		||||
                        int     *timeout)
 | 
			
		||||
{
 | 
			
		||||
  XClientEventSource *x_source = (XClientEventSource *) source;
 | 
			
		||||
 | 
			
		||||
  *timeout = -1;
 | 
			
		||||
 | 
			
		||||
  return XPending (x_source->xdisplay);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
x_event_source_check (GSource *source)
 | 
			
		||||
{
 | 
			
		||||
  XClientEventSource *x_source = (XClientEventSource *) source;
 | 
			
		||||
 | 
			
		||||
  return XPending (x_source->xdisplay);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
x_event_source_dispatch (GSource     *source,
 | 
			
		||||
                         GSourceFunc  callback,
 | 
			
		||||
                         gpointer     user_data)
 | 
			
		||||
{
 | 
			
		||||
  XClientEventSource *x_source = (XClientEventSource *) source;
 | 
			
		||||
 | 
			
		||||
  while (XPending (x_source->xdisplay))
 | 
			
		||||
    {
 | 
			
		||||
      GHashTableIter iter;
 | 
			
		||||
      XEvent event;
 | 
			
		||||
      gpointer value;
 | 
			
		||||
 | 
			
		||||
      XNextEvent (x_source->xdisplay, &event);
 | 
			
		||||
 | 
			
		||||
      g_hash_table_iter_init (&iter, windows);
 | 
			
		||||
      while (g_hash_table_iter_next (&iter, NULL, &value))
 | 
			
		||||
        {
 | 
			
		||||
          GList *l;
 | 
			
		||||
          GtkWidget *window = value;
 | 
			
		||||
          GList *handlers =
 | 
			
		||||
            g_object_get_qdata (G_OBJECT (window), event_handlers_quark);
 | 
			
		||||
 | 
			
		||||
          for (l = handlers; l; l = l->next)
 | 
			
		||||
            {
 | 
			
		||||
              XEventHandler handler = l->data;
 | 
			
		||||
              handler (window, &event);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
x_event_source_finalize (GSource *source)
 | 
			
		||||
{
 | 
			
		||||
  XClientEventSource *x_source = (XClientEventSource *) source;
 | 
			
		||||
 | 
			
		||||
  *x_source->self_ref = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GSourceFuncs x_event_funcs = {
 | 
			
		||||
  x_event_source_prepare,
 | 
			
		||||
  x_event_source_check,
 | 
			
		||||
  x_event_source_dispatch,
 | 
			
		||||
  x_event_source_finalize,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static GSource*
 | 
			
		||||
ensure_xsource_handler (GdkDisplay *gdkdisplay)
 | 
			
		||||
{
 | 
			
		||||
  static GSource *source = NULL;
 | 
			
		||||
  Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdkdisplay);
 | 
			
		||||
  XClientEventSource *x_source;
 | 
			
		||||
 | 
			
		||||
  if (source)
 | 
			
		||||
    return g_source_ref (source);
 | 
			
		||||
 | 
			
		||||
  source = g_source_new (&x_event_funcs, sizeof (XClientEventSource));
 | 
			
		||||
  x_source = (XClientEventSource *) source;
 | 
			
		||||
  x_source->self_ref = &source;
 | 
			
		||||
  x_source->xdisplay = xdisplay;
 | 
			
		||||
  x_source->event_poll_fd.fd = ConnectionNumber (xdisplay);
 | 
			
		||||
  x_source->event_poll_fd.events = G_IO_IN;
 | 
			
		||||
  g_source_add_poll (source, &x_source->event_poll_fd);
 | 
			
		||||
 | 
			
		||||
  g_source_set_priority (source, GDK_PRIORITY_EVENTS - 1);
 | 
			
		||||
  g_source_set_can_recurse (source, TRUE);
 | 
			
		||||
  g_source_attach (source, NULL);
 | 
			
		||||
 | 
			
		||||
  return source;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
window_has_x11_event_handler (GtkWidget     *window,
 | 
			
		||||
                              XEventHandler  handler)
 | 
			
		||||
{
 | 
			
		||||
  GList *handlers =
 | 
			
		||||
    g_object_get_qdata (G_OBJECT (window), event_handlers_quark);
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (handler, FALSE);
 | 
			
		||||
  g_return_val_if_fail (!wayland, FALSE);
 | 
			
		||||
 | 
			
		||||
  return g_list_find (handlers, handler) != NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unref_and_maybe_destroy_gsource (GSource *source)
 | 
			
		||||
{
 | 
			
		||||
  g_source_unref (source);
 | 
			
		||||
 | 
			
		||||
  if (source->ref_count == 1)
 | 
			
		||||
    g_source_destroy (source);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_add_x11_event_handler (GtkWidget     *window,
 | 
			
		||||
                              XEventHandler  handler)
 | 
			
		||||
{
 | 
			
		||||
  GSource *source;
 | 
			
		||||
  GList *handlers =
 | 
			
		||||
    g_object_get_qdata (G_OBJECT (window), event_handlers_quark);
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (!window_has_x11_event_handler (window, handler));
 | 
			
		||||
 | 
			
		||||
  source = ensure_xsource_handler (gtk_widget_get_display (window));
 | 
			
		||||
  g_object_set_qdata_full (G_OBJECT (window), event_source_quark, source,
 | 
			
		||||
                           (GDestroyNotify) unref_and_maybe_destroy_gsource);
 | 
			
		||||
 | 
			
		||||
  handlers = g_list_append (handlers, handler);
 | 
			
		||||
  g_object_set_qdata (G_OBJECT (window), event_handlers_quark, handlers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_remove_x11_event_handler (GtkWidget     *window,
 | 
			
		||||
                                 XEventHandler  handler)
 | 
			
		||||
{
 | 
			
		||||
  GList *handlers =
 | 
			
		||||
    g_object_get_qdata (G_OBJECT (window), event_handlers_quark);
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (window_has_x11_event_handler (window, handler));
 | 
			
		||||
 | 
			
		||||
  g_object_set_qdata (G_OBJECT (window), event_source_quark, NULL);
 | 
			
		||||
 | 
			
		||||
  handlers = g_list_remove (handlers, handler);
 | 
			
		||||
  g_object_set_qdata (G_OBJECT (window), event_handlers_quark, handlers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_take_focus (GtkWidget *window,
 | 
			
		||||
                   XEvent    *xevent)
 | 
			
		||||
{
 | 
			
		||||
  GdkWindow *gdkwindow = gtk_widget_get_window (window);
 | 
			
		||||
  GdkDisplay *display = gtk_widget_get_display (window);
 | 
			
		||||
  Atom wm_protocols =
 | 
			
		||||
    gdk_x11_get_xatom_by_name_for_display (display, "WM_PROTOCOLS");
 | 
			
		||||
  Atom wm_take_focus =
 | 
			
		||||
    gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
 | 
			
		||||
 | 
			
		||||
  if (xevent->xany.type != ClientMessage ||
 | 
			
		||||
      xevent->xany.window != GDK_WINDOW_XID (gdkwindow))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (xevent->xclient.message_type == wm_protocols &&
 | 
			
		||||
      (Atom) xevent->xclient.data.l[0] == wm_take_focus)
 | 
			
		||||
    {
 | 
			
		||||
      XSetInputFocus (xevent->xany.display,
 | 
			
		||||
                      GDK_WINDOW_XID (gdkwindow),
 | 
			
		||||
                      RevertToParent,
 | 
			
		||||
                      xevent->xclient.data.l[1]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
process_line (const char *line)
 | 
			
		||||
{
 | 
			
		||||
@@ -123,6 +308,9 @@ process_line (const char *line)
 | 
			
		||||
      gtk_window_set_title (GTK_WINDOW (window), title);
 | 
			
		||||
      g_free (title);
 | 
			
		||||
 | 
			
		||||
      g_object_set_qdata (G_OBJECT (window), can_take_focus_quark,
 | 
			
		||||
                          GUINT_TO_POINTER (TRUE));
 | 
			
		||||
 | 
			
		||||
      gtk_widget_realize (window);
 | 
			
		||||
 | 
			
		||||
      if (!wayland)
 | 
			
		||||
@@ -194,6 +382,130 @@ process_line (const char *line)
 | 
			
		||||
                                             NULL))
 | 
			
		||||
        g_print ("Fail to export handle for window id %s", argv[2]);
 | 
			
		||||
    }
 | 
			
		||||
  else if (strcmp (argv[0], "accept_focus") == 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (argc != 3)
 | 
			
		||||
        {
 | 
			
		||||
          g_print ("usage: %s <window-id> [true|false]", argv[0]);
 | 
			
		||||
          goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      GtkWidget *window = lookup_window (argv[1]);
 | 
			
		||||
      if (!window)
 | 
			
		||||
        {
 | 
			
		||||
          g_print ("unknown window %s", argv[1]);
 | 
			
		||||
          goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (!wayland &&
 | 
			
		||||
          window_has_x11_event_handler (window, handle_take_focus))
 | 
			
		||||
        {
 | 
			
		||||
          g_print ("Impossible to use %s for windows accepting take focus",
 | 
			
		||||
                   argv[1]);
 | 
			
		||||
          goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      gboolean enabled = g_ascii_strcasecmp (argv[2], "true") == 0;
 | 
			
		||||
      gtk_window_set_accept_focus (GTK_WINDOW (window), enabled);
 | 
			
		||||
    }
 | 
			
		||||
  else if (strcmp (argv[0], "can_take_focus") == 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (argc != 3)
 | 
			
		||||
        {
 | 
			
		||||
          g_print ("usage: %s <window-id> [true|false]", argv[0]);
 | 
			
		||||
          goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      GtkWidget *window = lookup_window (argv[1]);
 | 
			
		||||
      if (!window)
 | 
			
		||||
        {
 | 
			
		||||
          g_print ("unknown window %s", argv[1]);
 | 
			
		||||
          goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (wayland)
 | 
			
		||||
        {
 | 
			
		||||
          g_print ("%s not supported under wayland", argv[0]);
 | 
			
		||||
          goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (window_has_x11_event_handler (window, handle_take_focus))
 | 
			
		||||
        {
 | 
			
		||||
          g_print ("Impossible to change %s for windows accepting take focus",
 | 
			
		||||
                   argv[1]);
 | 
			
		||||
          goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      GdkDisplay *display = gdk_display_get_default ();
 | 
			
		||||
      GdkWindow *gdkwindow = gtk_widget_get_window (window);
 | 
			
		||||
      Display *xdisplay = gdk_x11_display_get_xdisplay (display);
 | 
			
		||||
      Window xwindow = GDK_WINDOW_XID (gdkwindow);
 | 
			
		||||
      Atom wm_take_focus = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
 | 
			
		||||
      gboolean add = g_ascii_strcasecmp(argv[2], "true") == 0;
 | 
			
		||||
      Atom *protocols = NULL;
 | 
			
		||||
      Atom *new_protocols;
 | 
			
		||||
      int n_protocols = 0;
 | 
			
		||||
      int i, n = 0;
 | 
			
		||||
 | 
			
		||||
      gdk_display_sync (display);
 | 
			
		||||
      XGetWMProtocols (xdisplay, xwindow, &protocols, &n_protocols);
 | 
			
		||||
      new_protocols = g_new0 (Atom, n_protocols + (add ? 1 : 0));
 | 
			
		||||
 | 
			
		||||
      for (i = 0; i < n_protocols; ++i)
 | 
			
		||||
        {
 | 
			
		||||
          if (protocols[i] != wm_take_focus)
 | 
			
		||||
            new_protocols[n++] = protocols[i];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (add)
 | 
			
		||||
        new_protocols[n++] = wm_take_focus;
 | 
			
		||||
 | 
			
		||||
      XSetWMProtocols (xdisplay, xwindow, new_protocols, n);
 | 
			
		||||
      g_object_set_qdata (G_OBJECT (window), can_take_focus_quark,
 | 
			
		||||
                          GUINT_TO_POINTER (add));
 | 
			
		||||
 | 
			
		||||
      XFree (new_protocols);
 | 
			
		||||
      XFree (protocols);
 | 
			
		||||
    }
 | 
			
		||||
  else if (strcmp (argv[0], "accept_take_focus") == 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (argc != 3)
 | 
			
		||||
        {
 | 
			
		||||
          g_print ("usage: %s <window-id> [true|false]", argv[0]);
 | 
			
		||||
          goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      GtkWidget *window = lookup_window (argv[1]);
 | 
			
		||||
      if (!window)
 | 
			
		||||
        {
 | 
			
		||||
          g_print ("unknown window %s", argv[1]);
 | 
			
		||||
          goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (wayland)
 | 
			
		||||
        {
 | 
			
		||||
          g_print ("%s not supported under wayland", argv[0]);
 | 
			
		||||
          goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (gtk_window_get_accept_focus (GTK_WINDOW (window)))
 | 
			
		||||
        {
 | 
			
		||||
          g_print ("%s not supported for input windows", argv[0]);
 | 
			
		||||
          goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (!g_object_get_qdata (G_OBJECT (window), can_take_focus_quark))
 | 
			
		||||
        {
 | 
			
		||||
          g_print ("%s not supported for windows with no WM_TAKE_FOCUS set",
 | 
			
		||||
                   argv[0]);
 | 
			
		||||
          goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (g_ascii_strcasecmp (argv[2], "true") == 0)
 | 
			
		||||
        window_add_x11_event_handler (window, handle_take_focus);
 | 
			
		||||
      else
 | 
			
		||||
        window_remove_x11_event_handler (window, handle_take_focus);
 | 
			
		||||
    }
 | 
			
		||||
  else if (strcmp (argv[0], "show") == 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (argc != 2)
 | 
			
		||||
@@ -442,6 +754,9 @@ main(int argc, char **argv)
 | 
			
		||||
 | 
			
		||||
  windows = g_hash_table_new_full (g_str_hash, g_str_equal,
 | 
			
		||||
                                   g_free, NULL);
 | 
			
		||||
  event_source_quark = g_quark_from_static_string ("event-source");
 | 
			
		||||
  event_handlers_quark = g_quark_from_static_string ("event-handlers");
 | 
			
		||||
  can_take_focus_quark = g_quark_from_static_string ("can-take-focus");
 | 
			
		||||
 | 
			
		||||
  GInputStream *raw_in = g_unix_input_stream_new (0, FALSE);
 | 
			
		||||
  GDataInputStream *in = g_data_input_stream_new (raw_in);
 | 
			
		||||
 
 | 
			
		||||
@@ -114,7 +114,7 @@ test_case_new (void)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
test_case_before_redraw (gpointer data)
 | 
			
		||||
test_case_loop_quit (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  TestCase *test = data;
 | 
			
		||||
 | 
			
		||||
@@ -123,6 +123,24 @@ test_case_before_redraw (gpointer data)
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
test_case_dispatch (TestCase *test,
 | 
			
		||||
                    GError  **error)
 | 
			
		||||
{
 | 
			
		||||
  /* 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_loop_quit,
 | 
			
		||||
                  test,
 | 
			
		||||
                  NULL);
 | 
			
		||||
  g_main_loop_run (test->loop);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
test_case_wait (TestCase *test,
 | 
			
		||||
                GError  **error)
 | 
			
		||||
@@ -139,16 +157,8 @@ test_case_wait (TestCase *test,
 | 
			
		||||
    if (!test_client_wait (value, error))
 | 
			
		||||
      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 wait until we've done any outstanding queued up work. */
 | 
			
		||||
  test_case_dispatch (test, error);
 | 
			
		||||
 | 
			
		||||
  /* Then set an XSync counter ourselves and and wait until
 | 
			
		||||
   * we receive the resulting event - this makes sure that we've
 | 
			
		||||
@@ -158,6 +168,17 @@ test_case_wait (TestCase *test,
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
test_case_sleep (TestCase  *test,
 | 
			
		||||
                 guint32    interval,
 | 
			
		||||
                 GError   **error)
 | 
			
		||||
{
 | 
			
		||||
  g_timeout_add_full (G_PRIORITY_LOW, interval, test_case_loop_quit, test, NULL);
 | 
			
		||||
  g_main_loop_run (test->loop);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define BAD_COMMAND(...)                                                \
 | 
			
		||||
  G_STMT_START {                                                        \
 | 
			
		||||
      g_set_error (error,                                               \
 | 
			
		||||
@@ -274,6 +295,37 @@ test_case_assert_stacking (TestCase *test,
 | 
			
		||||
  return *error == NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
test_case_assert_focused (TestCase    *test,
 | 
			
		||||
                          const char  *expected_window,
 | 
			
		||||
                          GError     **error)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display = meta_get_display ();
 | 
			
		||||
 | 
			
		||||
  if (!display->focus_window)
 | 
			
		||||
    {
 | 
			
		||||
      if (g_strcmp0 (expected_window, "none") != 0)
 | 
			
		||||
        {
 | 
			
		||||
          g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED,
 | 
			
		||||
                       "focus: expected='%s', actual='none'", expected_window);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      const char *focused = display->focus_window->title;
 | 
			
		||||
 | 
			
		||||
      if (g_str_has_prefix (focused, "test/"))
 | 
			
		||||
        focused += 5;
 | 
			
		||||
 | 
			
		||||
      if (g_strcmp0 (focused, expected_window) != 0)
 | 
			
		||||
        g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED,
 | 
			
		||||
                     "focus: expected='%s', actual='%s'",
 | 
			
		||||
                     expected_window, focused);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return *error == NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
test_case_check_xserver_stacking (TestCase *test,
 | 
			
		||||
                                  GError  **error)
 | 
			
		||||
@@ -435,6 +487,63 @@ test_case_do (TestCase *test,
 | 
			
		||||
      if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
      if (!test_client_do (client, error,
 | 
			
		||||
                           argv[0], window_id,
 | 
			
		||||
                           argv[2],
 | 
			
		||||
                           NULL))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  else if (strcmp (argv[0], "accept_focus") == 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (argc != 3 ||
 | 
			
		||||
          (g_ascii_strcasecmp (argv[2], "true") != 0 &&
 | 
			
		||||
           g_ascii_strcasecmp (argv[2], "false") != 0))
 | 
			
		||||
        BAD_COMMAND("usage: %s <client-id>/<window-id> [true|false]",
 | 
			
		||||
                    argv[0]);
 | 
			
		||||
 | 
			
		||||
      TestClient *client;
 | 
			
		||||
      const char *window_id;
 | 
			
		||||
      if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
      if (!test_client_do (client, error,
 | 
			
		||||
                           argv[0], window_id,
 | 
			
		||||
                           argv[2],
 | 
			
		||||
                           NULL))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  else if (strcmp (argv[0], "can_take_focus") == 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (argc != 3 ||
 | 
			
		||||
          (g_ascii_strcasecmp (argv[2], "true") != 0 &&
 | 
			
		||||
           g_ascii_strcasecmp (argv[2], "false") != 0))
 | 
			
		||||
        BAD_COMMAND("usage: %s <client-id>/<window-id> [true|false]",
 | 
			
		||||
                    argv[0]);
 | 
			
		||||
 | 
			
		||||
      TestClient *client;
 | 
			
		||||
      const char *window_id;
 | 
			
		||||
      if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
      if (!test_client_do (client, error,
 | 
			
		||||
                           argv[0], window_id,
 | 
			
		||||
                           argv[2],
 | 
			
		||||
                           NULL))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  else if (strcmp (argv[0], "accept_take_focus") == 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (argc != 3 ||
 | 
			
		||||
          (g_ascii_strcasecmp (argv[2], "true") != 0 &&
 | 
			
		||||
           g_ascii_strcasecmp (argv[2], "false") != 0))
 | 
			
		||||
        BAD_COMMAND("usage: %s <client-id>/<window-id> [true|false]",
 | 
			
		||||
                    argv[0]);
 | 
			
		||||
 | 
			
		||||
      TestClient *client;
 | 
			
		||||
      const char *window_id;
 | 
			
		||||
      if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
      if (!test_client_do (client, error,
 | 
			
		||||
                           argv[0], window_id,
 | 
			
		||||
                           argv[2],
 | 
			
		||||
@@ -514,6 +623,28 @@ test_case_do (TestCase *test,
 | 
			
		||||
      if (!test_case_wait (test, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  else if (strcmp (argv[0], "dispatch") == 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (argc != 1)
 | 
			
		||||
        BAD_COMMAND("usage: %s", argv[0]);
 | 
			
		||||
 | 
			
		||||
      if (!test_case_dispatch (test, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  else if (strcmp (argv[0], "sleep") == 0)
 | 
			
		||||
    {
 | 
			
		||||
      guint64 interval;
 | 
			
		||||
 | 
			
		||||
      if (argc != 2)
 | 
			
		||||
        BAD_COMMAND("usage: %s <milliseconds>", argv[0]);
 | 
			
		||||
 | 
			
		||||
      if (!g_ascii_string_to_unsigned (argv[1], 10, 0, G_MAXUINT32,
 | 
			
		||||
                                       &interval, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
      if (!test_case_sleep (test, (guint32) interval, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  else if (strcmp (argv[0], "assert_stacking") == 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (!test_case_assert_stacking (test, argv + 1, argc - 1, error))
 | 
			
		||||
@@ -522,6 +653,11 @@ test_case_do (TestCase *test,
 | 
			
		||||
      if (!test_case_check_xserver_stacking (test, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  else if (strcmp (argv[0], "assert_focused") == 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (!test_case_assert_focused (test, argv[1], error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      BAD_COMMAND("Unknown command %s", argv[0]);
 | 
			
		||||
 
 | 
			
		||||
@@ -266,7 +266,7 @@ meta_wayland_seat_free (MetaWaylandSeat *seat)
 | 
			
		||||
  meta_wayland_gtk_text_input_destroy (seat->gtk_text_input);
 | 
			
		||||
  meta_wayland_text_input_destroy (seat->text_input);
 | 
			
		||||
 | 
			
		||||
  g_slice_free (MetaWaylandSeat, seat);
 | 
			
		||||
  g_free (seat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
 
 | 
			
		||||
@@ -70,6 +70,8 @@ struct _MetaWaylandTextInput
 | 
			
		||||
  uint32_t content_type_purpose;
 | 
			
		||||
  uint32_t text_change_cause;
 | 
			
		||||
  gboolean enabled;
 | 
			
		||||
 | 
			
		||||
  guint done_idle_id;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaWaylandTextInputFocus
 | 
			
		||||
@@ -114,6 +116,52 @@ increment_serial (MetaWaylandTextInput *text_input,
 | 
			
		||||
                       GUINT_TO_POINTER (serial + 1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
done_idle_cb (gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  ClutterInputFocus *focus = user_data;
 | 
			
		||||
  MetaWaylandTextInput *text_input;
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
 | 
			
		||||
  text_input = META_WAYLAND_TEXT_INPUT_FOCUS (focus)->text_input;
 | 
			
		||||
 | 
			
		||||
  wl_resource_for_each (resource, &text_input->focus_resource_list)
 | 
			
		||||
    {
 | 
			
		||||
      zwp_text_input_v3_send_done (resource,
 | 
			
		||||
                                   lookup_serial (text_input, resource));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  text_input->done_idle_id = 0;
 | 
			
		||||
  return G_SOURCE_REMOVE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_text_input_focus_defer_done (ClutterInputFocus *focus)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandTextInput *text_input;
 | 
			
		||||
 | 
			
		||||
  text_input = META_WAYLAND_TEXT_INPUT_FOCUS (focus)->text_input;
 | 
			
		||||
 | 
			
		||||
  if (text_input->done_idle_id != 0)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* This operates on 3 principles:
 | 
			
		||||
   * - GDBus uses G_PRIORITY_DEFAULT to put messages in the thread default main
 | 
			
		||||
   *   context.
 | 
			
		||||
   * - All relevant ClutterInputFocus methods are ultimately backed by
 | 
			
		||||
   *   DBus methods inside IBus.
 | 
			
		||||
   * - We want to run .done after them all. The slightly lower
 | 
			
		||||
   *   G_PRIORITY_DEFAULT + 1 priority should ensure we at least group
 | 
			
		||||
   *   all messages seen so far.
 | 
			
		||||
   *
 | 
			
		||||
   * FIXME: .done may be delayed indefinitely if there's a high enough
 | 
			
		||||
   *        priority idle source in the main loop. It's unlikely that
 | 
			
		||||
   *        recurring idles run at this high priority though.
 | 
			
		||||
   */
 | 
			
		||||
  text_input->done_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT + 1,
 | 
			
		||||
                                              done_idle_cb, focus, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_text_input_focus_delete_surrounding (ClutterInputFocus *focus,
 | 
			
		||||
                                                  guint              cursor,
 | 
			
		||||
@@ -127,9 +175,9 @@ meta_wayland_text_input_focus_delete_surrounding (ClutterInputFocus *focus,
 | 
			
		||||
  wl_resource_for_each (resource, &text_input->focus_resource_list)
 | 
			
		||||
    {
 | 
			
		||||
      zwp_text_input_v3_send_delete_surrounding_text (resource, cursor, len);
 | 
			
		||||
      zwp_text_input_v3_send_done (resource,
 | 
			
		||||
                                   lookup_serial (text_input, resource));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_wayland_text_input_focus_defer_done (focus);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -145,9 +193,9 @@ meta_wayland_text_input_focus_commit_text (ClutterInputFocus *focus,
 | 
			
		||||
    {
 | 
			
		||||
      zwp_text_input_v3_send_preedit_string (resource, NULL, 0, 0);
 | 
			
		||||
      zwp_text_input_v3_send_commit_string (resource, text);
 | 
			
		||||
      zwp_text_input_v3_send_done (resource,
 | 
			
		||||
                                   lookup_serial (text_input, resource));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_wayland_text_input_focus_defer_done (focus);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -163,9 +211,9 @@ meta_wayland_text_input_focus_set_preedit_text (ClutterInputFocus *focus,
 | 
			
		||||
  wl_resource_for_each (resource, &text_input->focus_resource_list)
 | 
			
		||||
    {
 | 
			
		||||
      zwp_text_input_v3_send_preedit_string (resource, text, cursor, cursor);
 | 
			
		||||
      zwp_text_input_v3_send_done (resource,
 | 
			
		||||
                                   lookup_serial (text_input, resource));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_wayland_text_input_focus_defer_done (focus);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
@@ -1138,6 +1138,18 @@ process_selection_request (MetaX11Display *x11_display,
 | 
			
		||||
  meta_verbose ("Handled selection request\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
close_display_idle_cb (gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  MetaX11Display *x11_display = META_X11_DISPLAY (user_data);
 | 
			
		||||
 | 
			
		||||
  meta_display_close (x11_display->display,
 | 
			
		||||
                      x11_display->xselectionclear_timestamp);
 | 
			
		||||
  x11_display->display_close_idle = 0;
 | 
			
		||||
 | 
			
		||||
  return G_SOURCE_REMOVE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
process_selection_clear (MetaX11Display *x11_display,
 | 
			
		||||
                         XEvent         *event)
 | 
			
		||||
@@ -1163,8 +1175,13 @@ process_selection_clear (MetaX11Display *x11_display,
 | 
			
		||||
  meta_verbose ("Got selection clear for on display %s\n",
 | 
			
		||||
                x11_display->name);
 | 
			
		||||
 | 
			
		||||
  meta_display_close (x11_display->display,
 | 
			
		||||
                      event->xselectionclear.time);
 | 
			
		||||
  /* We can't close a GdkDisplay in an even handler. */
 | 
			
		||||
  if (!x11_display->display_close_idle)
 | 
			
		||||
    {
 | 
			
		||||
      x11_display->xselectionclear_timestamp = event->xselectionclear.time;
 | 
			
		||||
      x11_display->display_close_idle = g_idle_add (close_display_idle_cb, x11_display);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1818,11 +1835,8 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display,
 | 
			
		||||
    {
 | 
			
		||||
      if (process_selection_clear (x11_display, event))
 | 
			
		||||
        {
 | 
			
		||||
          /* This means we called meta_display_unmanage_screen, which
 | 
			
		||||
           * means the MetaDisplay is effectively dead. We don't want
 | 
			
		||||
           * to poke into display->current_time below, since that would
 | 
			
		||||
           * crash, so just directly return. */
 | 
			
		||||
          return TRUE;
 | 
			
		||||
          bypass_gtk = TRUE;
 | 
			
		||||
          goto out;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -92,6 +92,9 @@ struct _MetaX11Display
 | 
			
		||||
  Atom wm_sn_atom;
 | 
			
		||||
  guint32 wm_sn_timestamp;
 | 
			
		||||
 | 
			
		||||
  guint display_close_idle;
 | 
			
		||||
  guint32 xselectionclear_timestamp;
 | 
			
		||||
 | 
			
		||||
  Window wm_cm_selection_window;
 | 
			
		||||
 | 
			
		||||
  Window composite_overlay_window;
 | 
			
		||||
 
 | 
			
		||||
@@ -215,6 +215,12 @@ meta_x11_display_dispose (GObject *object)
 | 
			
		||||
      x11_display->gdk_display = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (x11_display->display_close_idle)
 | 
			
		||||
    {
 | 
			
		||||
      g_source_remove (x11_display->display_close_idle);
 | 
			
		||||
      x11_display->display_close_idle = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_free (x11_display->name);
 | 
			
		||||
  x11_display->name = NULL;
 | 
			
		||||
 | 
			
		||||
@@ -1186,6 +1192,9 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
 | 
			
		||||
  x11_display->timestamp_pinging_window = None;
 | 
			
		||||
  x11_display->wm_sn_selection_window = None;
 | 
			
		||||
 | 
			
		||||
  x11_display->display_close_idle = 0;
 | 
			
		||||
  x11_display->xselectionclear_timestamp = 0;
 | 
			
		||||
 | 
			
		||||
  x11_display->last_bell_time = 0;
 | 
			
		||||
  x11_display->focus_serial = 0;
 | 
			
		||||
  x11_display->server_focus_window = None;
 | 
			
		||||
 
 | 
			
		||||
@@ -55,8 +55,15 @@
 | 
			
		||||
#include "backends/meta-logical-monitor.h"
 | 
			
		||||
#include "backends/x11/meta-backend-x11.h"
 | 
			
		||||
 | 
			
		||||
#define TAKE_FOCUS_FALLBACK_DELAY_MS 150
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaWindowX11, meta_window_x11, META_TYPE_WINDOW)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_x11_maybe_focus_delayed (MetaWindow *window,
 | 
			
		||||
                                     GQueue     *other_focus_candidates,
 | 
			
		||||
                                     guint32     timestamp);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_x11_init (MetaWindowX11 *window_x11)
 | 
			
		||||
{
 | 
			
		||||
@@ -734,6 +741,160 @@ request_take_focus (MetaWindow *window,
 | 
			
		||||
  send_icccm_message (window, display->x11_display->atom_WM_TAKE_FOCUS, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  MetaWindow *window;
 | 
			
		||||
  GQueue *pending_focus_candidates;
 | 
			
		||||
  guint32 timestamp;
 | 
			
		||||
  guint timeout_id;
 | 
			
		||||
  gulong unmanaged_id;
 | 
			
		||||
  gulong focused_changed_id;
 | 
			
		||||
} MetaWindowX11DelayedFocusData;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
disconnect_pending_focus_window_signals (MetaWindow *window,
 | 
			
		||||
                                         GQueue     *focus_candidates)
 | 
			
		||||
{
 | 
			
		||||
  g_signal_handlers_disconnect_by_func (window, g_queue_remove,
 | 
			
		||||
                                        focus_candidates);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_x11_delayed_focus_data_free (MetaWindowX11DelayedFocusData *data)
 | 
			
		||||
{
 | 
			
		||||
  g_signal_handler_disconnect (data->window, data->unmanaged_id);
 | 
			
		||||
  g_signal_handler_disconnect (data->window->display, data->focused_changed_id);
 | 
			
		||||
 | 
			
		||||
  if (data->pending_focus_candidates)
 | 
			
		||||
    {
 | 
			
		||||
      g_queue_foreach (data->pending_focus_candidates,
 | 
			
		||||
                       (GFunc) disconnect_pending_focus_window_signals,
 | 
			
		||||
                       data->pending_focus_candidates);
 | 
			
		||||
      g_queue_free (data->pending_focus_candidates);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (data->timeout_id)
 | 
			
		||||
    g_source_remove (data->timeout_id);
 | 
			
		||||
 | 
			
		||||
  g_free (data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
focus_candidates_maybe_take_and_focus_next (GQueue  **focus_candidates_ptr,
 | 
			
		||||
                                            guint32   timestamp)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindow *focus_window;
 | 
			
		||||
  GQueue *focus_candidates;
 | 
			
		||||
 | 
			
		||||
  g_assert (*focus_candidates_ptr);
 | 
			
		||||
 | 
			
		||||
  if (g_queue_is_empty (*focus_candidates_ptr))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  focus_candidates = g_steal_pointer (focus_candidates_ptr);
 | 
			
		||||
  focus_window = g_queue_pop_head (focus_candidates);
 | 
			
		||||
 | 
			
		||||
  disconnect_pending_focus_window_signals (focus_window, focus_candidates);
 | 
			
		||||
  meta_window_x11_maybe_focus_delayed (focus_window, focus_candidates, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
focus_window_delayed_timeout (gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowX11DelayedFocusData *data = user_data;
 | 
			
		||||
  MetaWindow *window = data->window;
 | 
			
		||||
  guint32 timestamp = data->timestamp;
 | 
			
		||||
 | 
			
		||||
  focus_candidates_maybe_take_and_focus_next (&data->pending_focus_candidates,
 | 
			
		||||
                                              timestamp);
 | 
			
		||||
 | 
			
		||||
  data->timeout_id = 0;
 | 
			
		||||
  meta_window_x11_delayed_focus_data_free (data);
 | 
			
		||||
 | 
			
		||||
  meta_window_focus (window, timestamp);
 | 
			
		||||
 | 
			
		||||
  return G_SOURCE_REMOVE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_x11_maybe_focus_delayed (MetaWindow *window,
 | 
			
		||||
                                     GQueue     *other_focus_candidates,
 | 
			
		||||
                                     guint32     timestamp)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowX11DelayedFocusData *data;
 | 
			
		||||
 | 
			
		||||
  data = g_new0 (MetaWindowX11DelayedFocusData, 1);
 | 
			
		||||
  data->window = window;
 | 
			
		||||
  data->timestamp = timestamp;
 | 
			
		||||
  data->pending_focus_candidates = other_focus_candidates;
 | 
			
		||||
 | 
			
		||||
  meta_topic (META_DEBUG_FOCUS,
 | 
			
		||||
              "Requesting delayed focus to %s\n", window->desc);
 | 
			
		||||
 | 
			
		||||
  data->unmanaged_id =
 | 
			
		||||
    g_signal_connect_swapped (window, "unmanaged",
 | 
			
		||||
                              G_CALLBACK (meta_window_x11_delayed_focus_data_free),
 | 
			
		||||
                              data);
 | 
			
		||||
 | 
			
		||||
  data->focused_changed_id =
 | 
			
		||||
    g_signal_connect_swapped (window->display, "notify::focus-window",
 | 
			
		||||
                              G_CALLBACK (meta_window_x11_delayed_focus_data_free),
 | 
			
		||||
                              data);
 | 
			
		||||
 | 
			
		||||
  data->timeout_id = g_timeout_add (TAKE_FOCUS_FALLBACK_DELAY_MS,
 | 
			
		||||
                                    focus_window_delayed_timeout, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
maybe_focus_default_window (MetaDisplay *display,
 | 
			
		||||
                            MetaWindow  *not_this_one,
 | 
			
		||||
                            guint32      timestamp)
 | 
			
		||||
{
 | 
			
		||||
  MetaWorkspace *workspace;
 | 
			
		||||
  MetaStack *stack = display->stack;
 | 
			
		||||
  g_autoptr (GList) focusable_windows = NULL;
 | 
			
		||||
  g_autoptr (GQueue) focus_candidates = NULL;
 | 
			
		||||
  GList *l;
 | 
			
		||||
 | 
			
		||||
  if (not_this_one && not_this_one->workspace)
 | 
			
		||||
    workspace = not_this_one->workspace;
 | 
			
		||||
  else
 | 
			
		||||
    workspace = display->workspace_manager->active_workspace;
 | 
			
		||||
 | 
			
		||||
   /* Go through all the focusable windows and try to focus them
 | 
			
		||||
    * in order, waiting for a delay. The first one that replies to
 | 
			
		||||
    * the request (in case of take focus windows) changing the display
 | 
			
		||||
    * focused window, will stop the chained requests.
 | 
			
		||||
    */
 | 
			
		||||
  focusable_windows =
 | 
			
		||||
    meta_stack_get_default_focus_candidates (stack, workspace);
 | 
			
		||||
  focus_candidates = g_queue_new ();
 | 
			
		||||
 | 
			
		||||
  for (l = g_list_last (focusable_windows); l; l = l->prev)
 | 
			
		||||
    {
 | 
			
		||||
      MetaWindow *focus_window = l->data;
 | 
			
		||||
 | 
			
		||||
      if (focus_window == not_this_one)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      g_queue_push_tail (focus_candidates, focus_window);
 | 
			
		||||
      g_signal_connect_swapped (focus_window, "unmanaged",
 | 
			
		||||
                                G_CALLBACK (g_queue_remove),
 | 
			
		||||
                                focus_candidates);
 | 
			
		||||
 | 
			
		||||
      if (!META_IS_WINDOW_X11 (focus_window))
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      if (focus_window->input)
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      if (focus_window->shaded && focus_window->frame)
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  focus_candidates_maybe_take_and_focus_next (&focus_candidates, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_x11_focus (MetaWindow *window,
 | 
			
		||||
                       guint32     timestamp)
 | 
			
		||||
@@ -783,13 +944,20 @@ meta_window_x11_focus (MetaWindow *window,
 | 
			
		||||
               * Normally, we want to just leave the focus undisturbed until
 | 
			
		||||
               * the window responds to WM_TAKE_FOCUS, but if we're unmanaging
 | 
			
		||||
               * the current focus window we *need* to move the focus away, so
 | 
			
		||||
               * we focus the no_focus_window now (and set
 | 
			
		||||
               * display->focus_window to that) before sending WM_TAKE_FOCUS.
 | 
			
		||||
               * we focus the no focus window before sending WM_TAKE_FOCUS,
 | 
			
		||||
               * and eventually the default focus windwo excluding this one,
 | 
			
		||||
               * if meanwhile we don't get any focus request.
 | 
			
		||||
               */
 | 
			
		||||
              if (window->display->focus_window != NULL &&
 | 
			
		||||
                  window->display->focus_window->unmanaging)
 | 
			
		||||
                meta_x11_display_focus_the_no_focus_window (window->display->x11_display,
 | 
			
		||||
                                                            timestamp);
 | 
			
		||||
                {
 | 
			
		||||
                  MetaX11Display *x11_display = window->display->x11_display;
 | 
			
		||||
 | 
			
		||||
                  meta_x11_display_focus_the_no_focus_window (x11_display,
 | 
			
		||||
                                                              timestamp);
 | 
			
		||||
                  maybe_focus_default_window (window->display, window,
 | 
			
		||||
                                              timestamp);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          request_take_focus (window, timestamp);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user