Compare commits
	
		
			26 Commits
		
	
	
		
			gnome-3-12
			...
			3.8.4
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					17185452c6 | ||
| 
						 | 
					534774a72f | ||
| 
						 | 
					efefb40e70 | ||
| 
						 | 
					ca4e1fd4c9 | ||
| 
						 | 
					74fb5a83dd | ||
| 
						 | 
					02ecca502e | ||
| 
						 | 
					e36eb3e91a | ||
| 
						 | 
					de6d9591c4 | ||
| 
						 | 
					a20401782e | ||
| 
						 | 
					79ea9f0b0f | ||
| 
						 | 
					7b36dcf4a0 | ||
| 
						 | 
					edfde6221f | ||
| 
						 | 
					1ad1357745 | ||
| 
						 | 
					fb0999a1a9 | ||
| 
						 | 
					7186ddff49 | ||
| 
						 | 
					d664cfcc90 | ||
| 
						 | 
					056cc16b82 | ||
| 
						 | 
					6c4bcecc00 | ||
| 
						 | 
					f531960b6a | ||
| 
						 | 
					e15792c983 | ||
| 
						 | 
					1627044c39 | ||
| 
						 | 
					5615e36112 | ||
| 
						 | 
					2c210e0e25 | ||
| 
						 | 
					1c06f0dc09 | ||
| 
						 | 
					51d98be1f2 | ||
| 
						 | 
					859d231129 | 
							
								
								
									
										36
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								NEWS
									
									
									
									
									
								
							@@ -1,3 +1,39 @@
 | 
			
		||||
3.8.4
 | 
			
		||||
=====
 | 
			
		||||
* Workaround failure to bring back shell interface after fullscreen game in some situations [Adel; #701224]
 | 
			
		||||
* Fix sluggish and stuck pointers moving windows [Adel, Jasper: #699777]
 | 
			
		||||
* Reduce log spew [Adel, Jasper; #702564, #703970]
 | 
			
		||||
* Touch screen fixes [Jasper: #697192]
 | 
			
		||||
* Fix rendering of large background images [Jasper, Ray: #702283]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
 Adel Gadllah, Jasper St. Pierre, Ray Strode
 | 
			
		||||
 | 
			
		||||
3.8.3
 | 
			
		||||
=====
 | 
			
		||||
* Add support for string-array preferences [Florian; #700223]
 | 
			
		||||
* Fix shade window action [Stef; #693714]
 | 
			
		||||
* Add API to freeze/unfreeze the keyboard [Rui; #697001]
 | 
			
		||||
* Grab and emit a signal when XK_ISO_Next_Group is pressed [Rui; #697002]
 | 
			
		||||
* Ensure events are always reported to the grab window [Rui; #701219]
 | 
			
		||||
* Use new clutter_stage_set_paint_callback() function to prevent dropping
 | 
			
		||||
  frames with frame synced toolkits [Owen; #698794]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Rui Matos, Florian Müllner, Stef Walter, Owen W. Taylor
 | 
			
		||||
 | 
			
		||||
3.8.2
 | 
			
		||||
=====
 | 
			
		||||
* Fix miscellaneous memory leaks [Pavel; #698710]
 | 
			
		||||
* Fix binding remaining grabbed after clearing all strokes [Rui; #697000]
 | 
			
		||||
* Misc fixes [Stef; #698179]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Rui Matos, Pavel Vasin, Stef Walter
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Kjartan Maraas [nb]
 | 
			
		||||
 | 
			
		||||
3.8.1
 | 
			
		||||
=====
 | 
			
		||||
* Fix crash when getting default font [Bastien; #696814]
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ AC_PREREQ(2.50)
 | 
			
		||||
 | 
			
		||||
m4_define([mutter_major_version], [3])
 | 
			
		||||
m4_define([mutter_minor_version], [8])
 | 
			
		||||
m4_define([mutter_micro_version], [1])
 | 
			
		||||
m4_define([mutter_micro_version], [4])
 | 
			
		||||
 | 
			
		||||
m4_define([mutter_version],
 | 
			
		||||
          [mutter_major_version.mutter_minor_version.mutter_micro_version])
 | 
			
		||||
@@ -73,7 +73,7 @@ MUTTER_PC_MODULES="
 | 
			
		||||
   cairo >= 1.10.0
 | 
			
		||||
   gsettings-desktop-schemas >= 3.7.3
 | 
			
		||||
   xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0
 | 
			
		||||
   $CLUTTER_PACKAGE >= 1.13.5
 | 
			
		||||
   $CLUTTER_PACKAGE >= 1.14.3
 | 
			
		||||
   cogl-1.0 >= 1.13.3
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								po/nb.po
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								po/nb.po
									
									
									
									
									
								
							@@ -6,7 +6,7 @@ msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: mutter 3.8.x\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: \n"
 | 
			
		||||
"POT-Creation-Date: 2013-04-03 14:10+0200\n"
 | 
			
		||||
"POT-Creation-Date: 2013-05-13 10:30+0200\n"
 | 
			
		||||
"PO-Revision-Date: 2013-04-03 14:11+0200\n"
 | 
			
		||||
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
 | 
			
		||||
"Language-Team: Norwegian bokmål <i18n-no@lister.ping.uio.no>\n"
 | 
			
		||||
@@ -212,7 +212,7 @@ msgid ""
 | 
			
		||||
"\"."
 | 
			
		||||
msgstr "En annen compositing manager kjører skjerm %i på display «%s»."
 | 
			
		||||
 | 
			
		||||
#: ../src/compositor/meta-background.c:1064
 | 
			
		||||
#: ../src/compositor/meta-background.c:1076
 | 
			
		||||
msgid "background texture could not be created from file"
 | 
			
		||||
msgstr "bakgrunnstekstur kunne ikke lages fra fil"
 | 
			
		||||
 | 
			
		||||
@@ -260,7 +260,7 @@ msgstr "Mangler utvidelsen %s som kreves for komposittfunksjon"
 | 
			
		||||
msgid "Failed to open X Window System display '%s'\n"
 | 
			
		||||
msgstr "Feil under åpning av X Window System skjerm «%s»\n"
 | 
			
		||||
 | 
			
		||||
#: ../src/core/keybindings.c:935
 | 
			
		||||
#: ../src/core/keybindings.c:970
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"Some other program is already using the key %s with modifiers %x as a "
 | 
			
		||||
@@ -269,7 +269,7 @@ msgstr ""
 | 
			
		||||
"Et annet program bruker allerede nøkkelen %s med modifikatorer %x som "
 | 
			
		||||
"binding\n"
 | 
			
		||||
 | 
			
		||||
#: ../src/core/keybindings.c:1135
 | 
			
		||||
#: ../src/core/keybindings.c:1151
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "\"%s\" is not a valid accelerator\n"
 | 
			
		||||
msgstr "«%s» er ikke en gyldig aksellerator\n"
 | 
			
		||||
@@ -355,7 +355,7 @@ msgstr ""
 | 
			
		||||
"«%s» funnet i konfigurasjonsdatabasen er ikke en gyldig verdi for endring av "
 | 
			
		||||
"musknapp\n"
 | 
			
		||||
 | 
			
		||||
#: ../src/core/prefs.c:1788
 | 
			
		||||
#: ../src/core/prefs.c:1789
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"\"%s\" found in configuration database is not a valid value for keybinding "
 | 
			
		||||
@@ -364,7 +364,7 @@ msgstr ""
 | 
			
		||||
"«%s» funnet i konfigurasjonsdatabasen er ikke en gyldig verdi for "
 | 
			
		||||
"tastaturbinding «%s»\n"
 | 
			
		||||
 | 
			
		||||
#: ../src/core/prefs.c:1887
 | 
			
		||||
#: ../src/core/prefs.c:1888
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Workspace %d"
 | 
			
		||||
msgstr "Arbeidsområde %d"
 | 
			
		||||
@@ -492,7 +492,7 @@ msgid "Window manager error: "
 | 
			
		||||
msgstr "Feil i vindushåndterer: "
 | 
			
		||||
 | 
			
		||||
#. first time through
 | 
			
		||||
#: ../src/core/window.c:7596
 | 
			
		||||
#: ../src/core/window.c:7598
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
 | 
			
		||||
@@ -508,7 +508,7 @@ msgstr ""
 | 
			
		||||
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
 | 
			
		||||
#. * about these apps but make them work.
 | 
			
		||||
#.
 | 
			
		||||
#: ../src/core/window.c:8320
 | 
			
		||||
#: ../src/core/window.c:8322
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
 | 
			
		||||
@@ -684,7 +684,9 @@ msgstr "Maksimer vinduer automatisk hvis de er nesten like store som skjermen"
 | 
			
		||||
msgid ""
 | 
			
		||||
"If enabled, new windows that are initially the size of the monitor "
 | 
			
		||||
"automatically get maximized."
 | 
			
		||||
msgstr "Nye vinduer som i utgangspunktet er samme størrelse som skjermen vil automatisk bli maksimert hvis denne slås på."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Nye vinduer som i utgangspunktet er samme størrelse som skjermen vil "
 | 
			
		||||
"automatisk bli maksimert hvis denne slås på."
 | 
			
		||||
 | 
			
		||||
#: ../src/org.gnome.mutter.gschema.xml.in.h:19
 | 
			
		||||
msgid "Select window from tab popup"
 | 
			
		||||
 
 | 
			
		||||
@@ -514,20 +514,20 @@ meta_check_end_modal (MetaScreen *screen)
 | 
			
		||||
    {
 | 
			
		||||
      meta_end_modal_for_plugin (screen,
 | 
			
		||||
                                   compositor->modal_plugin,
 | 
			
		||||
                                   CurrentTime);
 | 
			
		||||
 | 
			
		||||
                                 CurrentTime);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
after_stage_paint (gpointer data)
 | 
			
		||||
static void
 | 
			
		||||
after_stage_paint (ClutterStage *stage,
 | 
			
		||||
                   gpointer      data)
 | 
			
		||||
{
 | 
			
		||||
  MetaCompScreen *info = (MetaCompScreen*) data;
 | 
			
		||||
  GList *l;
 | 
			
		||||
 | 
			
		||||
  for (l = info->windows; l; l = l->next)
 | 
			
		||||
    meta_window_actor_post_paint (l->data);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -608,9 +608,10 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
 | 
			
		||||
 | 
			
		||||
  info->stage = clutter_stage_new ();
 | 
			
		||||
 | 
			
		||||
  clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
 | 
			
		||||
                                         after_stage_paint,
 | 
			
		||||
                                         info, NULL);
 | 
			
		||||
  clutter_stage_set_paint_callback (CLUTTER_STAGE (info->stage),
 | 
			
		||||
                                    after_stage_paint,
 | 
			
		||||
                                    info,
 | 
			
		||||
                                    NULL);
 | 
			
		||||
 | 
			
		||||
  clutter_stage_set_sync_delay (CLUTTER_STAGE (info->stage), META_SYNC_DELAY);
 | 
			
		||||
 | 
			
		||||
@@ -638,6 +639,9 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
 | 
			
		||||
    XISetMask (mask.mask, XI_FocusIn);
 | 
			
		||||
    XISetMask (mask.mask, XI_FocusOut);
 | 
			
		||||
    XISetMask (mask.mask, XI_Motion);
 | 
			
		||||
    XIClearMask (mask.mask, XI_TouchBegin);
 | 
			
		||||
    XIClearMask (mask.mask, XI_TouchEnd);
 | 
			
		||||
    XIClearMask (mask.mask, XI_TouchUpdate);
 | 
			
		||||
    XISelectEvents (xdisplay, xwin, &mask, 1);
 | 
			
		||||
 | 
			
		||||
    event_mask = ExposureMask | PropertyChangeMask | StructureNotifyMask;
 | 
			
		||||
@@ -1566,8 +1570,10 @@ void
 | 
			
		||||
meta_enable_unredirect_for_screen (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
  MetaCompScreen *info = meta_screen_get_compositor_data (screen);
 | 
			
		||||
  if (info != NULL)
 | 
			
		||||
   info->disable_unredirect_count = MAX(0, info->disable_unredirect_count - 1);
 | 
			
		||||
  if (info != NULL && info->disable_unredirect_count == 0)
 | 
			
		||||
    g_warning ("Called enable_unredirect_for_screen while unredirection is enabled.");
 | 
			
		||||
  if (info != NULL && info->disable_unredirect_count > 0)
 | 
			
		||||
   info->disable_unredirect_count = info->disable_unredirect_count - 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define FLASH_TIME_MS 50
 | 
			
		||||
 
 | 
			
		||||
@@ -472,6 +472,17 @@ meta_background_dispose (GObject *object)
 | 
			
		||||
  G_OBJECT_CLASS (meta_background_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_background_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackground        *self = META_BACKGROUND (object);
 | 
			
		||||
  MetaBackgroundPrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  g_free (priv->filename);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (meta_background_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
ensure_pipeline (MetaBackground *self)
 | 
			
		||||
{
 | 
			
		||||
@@ -643,6 +654,7 @@ meta_background_class_init (MetaBackgroundClass *klass)
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (MetaBackgroundPrivate));
 | 
			
		||||
 | 
			
		||||
  object_class->dispose = meta_background_dispose;
 | 
			
		||||
  object_class->finalize = meta_background_finalize;
 | 
			
		||||
  object_class->set_property = meta_background_set_property;
 | 
			
		||||
  object_class->get_property = meta_background_get_property;
 | 
			
		||||
 | 
			
		||||
@@ -879,7 +891,7 @@ meta_background_load_gradient (MetaBackground             *self,
 | 
			
		||||
  pixels[7] = second_color->alpha;
 | 
			
		||||
 | 
			
		||||
  texture = cogl_texture_new_from_data (width, height,
 | 
			
		||||
                                        COGL_TEXTURE_NO_SLICING,
 | 
			
		||||
                                        COGL_TEXTURE_NONE,
 | 
			
		||||
                                        COGL_PIXEL_FORMAT_RGBA_8888,
 | 
			
		||||
                                        COGL_PIXEL_FORMAT_ANY,
 | 
			
		||||
                                        4,
 | 
			
		||||
 
 | 
			
		||||
@@ -1645,7 +1645,7 @@ meta_window_actor_get_obscured_region (MetaWindowActor *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->back_pixmap && priv->opacity == 0xff)
 | 
			
		||||
  if (priv->back_pixmap && priv->opacity == 0xff && !priv->window->shaded)
 | 
			
		||||
    return priv->opaque_region;
 | 
			
		||||
  else
 | 
			
		||||
    return NULL;
 | 
			
		||||
@@ -2214,7 +2214,10 @@ check_needs_reshape (MetaWindowActor *self)
 | 
			
		||||
  client_area.x = borders.total.left;
 | 
			
		||||
  client_area.y = borders.total.top;
 | 
			
		||||
  client_area.width = priv->window->rect.width;
 | 
			
		||||
  client_area.height = priv->window->rect.height;
 | 
			
		||||
  if (priv->window->shaded)
 | 
			
		||||
    client_area.height = 0;
 | 
			
		||||
  else
 | 
			
		||||
    client_area.height = priv->window->rect.height;
 | 
			
		||||
 | 
			
		||||
  meta_shaped_texture_set_mask_texture (META_SHAPED_TEXTURE (priv->actor), NULL);
 | 
			
		||||
  g_clear_pointer (&priv->shape_region, cairo_region_destroy);
 | 
			
		||||
 
 | 
			
		||||
@@ -59,6 +59,8 @@ struct _MetaBarrierPrivate
 | 
			
		||||
  PointerBarrier xbarrier;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void meta_barrier_event_unref (MetaBarrierEvent *event);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_barrier_get_property (GObject    *object,
 | 
			
		||||
                           guint       prop_id,
 | 
			
		||||
@@ -359,6 +361,8 @@ meta_barrier_fire_event (MetaBarrier    *barrier,
 | 
			
		||||
    default:
 | 
			
		||||
      g_assert_not_reached ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_barrier_event_unref (event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
 
 | 
			
		||||
@@ -239,6 +239,8 @@ struct _MetaDisplay
 | 
			
		||||
  unsigned int meta_mask;
 | 
			
		||||
  MetaKeyCombo overlay_key_combo;
 | 
			
		||||
  gboolean overlay_key_only_pressed;
 | 
			
		||||
  MetaKeyCombo *iso_next_group_combos;
 | 
			
		||||
  int n_iso_next_group_combos;
 | 
			
		||||
  
 | 
			
		||||
  /* Monitor cache */
 | 
			
		||||
  unsigned int monitor_cache_invalidated : 1;
 | 
			
		||||
@@ -458,6 +460,7 @@ void meta_display_overlay_key_activate (MetaDisplay *display);
 | 
			
		||||
void meta_display_accelerator_activate (MetaDisplay *display,
 | 
			
		||||
                                        guint        action,
 | 
			
		||||
                                        guint        deviceid);
 | 
			
		||||
gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display);
 | 
			
		||||
 | 
			
		||||
/* In above-tab-keycode.c */
 | 
			
		||||
guint meta_display_get_above_tab_keycode (MetaDisplay *display);
 | 
			
		||||
 
 | 
			
		||||
@@ -139,6 +139,7 @@ enum
 | 
			
		||||
{
 | 
			
		||||
  OVERLAY_KEY,
 | 
			
		||||
  ACCELERATOR_ACTIVATED,
 | 
			
		||||
  MODIFIERS_ACCELERATOR_ACTIVATED,
 | 
			
		||||
  FOCUS_WINDOW,
 | 
			
		||||
  WINDOW_CREATED,
 | 
			
		||||
  WINDOW_DEMANDS_ATTENTION,
 | 
			
		||||
@@ -255,6 +256,25 @@ meta_display_class_init (MetaDisplayClass *klass)
 | 
			
		||||
                  NULL, NULL, NULL,
 | 
			
		||||
                  G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * MetaDisplay::modifiers-accelerator-activated:
 | 
			
		||||
   * @display: the #MetaDisplay instance
 | 
			
		||||
   *
 | 
			
		||||
   * The ::modifiers-accelerator-activated signal will be emitted when
 | 
			
		||||
   * a special modifiers-only keybinding is activated.
 | 
			
		||||
   *
 | 
			
		||||
   * Returns: %TRUE means that the keyboard device should remain
 | 
			
		||||
   *    frozen and %FALSE for the default behavior of unfreezing the
 | 
			
		||||
   *    keyboard.
 | 
			
		||||
   */
 | 
			
		||||
  display_signals[MODIFIERS_ACCELERATOR_ACTIVATED] =
 | 
			
		||||
    g_signal_new ("modifiers-accelerator-activated",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  0,
 | 
			
		||||
                  g_signal_accumulator_first_wins, NULL, NULL,
 | 
			
		||||
                  G_TYPE_BOOLEAN, 0);
 | 
			
		||||
 | 
			
		||||
  display_signals[WINDOW_CREATED] =
 | 
			
		||||
    g_signal_new ("window-created",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
@@ -3537,6 +3557,12 @@ meta_spew_event (MetaDisplay *display,
 | 
			
		||||
  if (event->type == (display->damage_event_base + XDamageNotify))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (event->type == (display->xsync_event_base + XSyncAlarmNotify))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (event->type == PropertyNotify && event->xproperty.atom == display->atom__NET_WM_USER_TIME)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  input_event = get_input_event (display, event);
 | 
			
		||||
 | 
			
		||||
  if (input_event)
 | 
			
		||||
@@ -5681,6 +5707,16 @@ meta_display_accelerator_activate (MetaDisplay *display,
 | 
			
		||||
                 0, action, deviceid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_display_modifiers_accelerator_activate (MetaDisplay *display)
 | 
			
		||||
{
 | 
			
		||||
  gboolean freeze;
 | 
			
		||||
 | 
			
		||||
  g_signal_emit (display, display_signals[MODIFIERS_ACCELERATOR_ACTIVATED], 0, &freeze);
 | 
			
		||||
 | 
			
		||||
  return freeze;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_display_get_compositor_version (MetaDisplay *display,
 | 
			
		||||
                                     int         *major,
 | 
			
		||||
 
 | 
			
		||||
@@ -302,6 +302,172 @@ reload_modmap (MetaDisplay *display)
 | 
			
		||||
              display->meta_mask);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Original code from gdk_x11_keymap_get_entries_for_keyval() in
 | 
			
		||||
 * gdkkeys-x11.c */
 | 
			
		||||
static int
 | 
			
		||||
get_keycodes_for_keysym (MetaDisplay  *display,
 | 
			
		||||
                         int           keysym,
 | 
			
		||||
                         int         **keycodes)
 | 
			
		||||
{
 | 
			
		||||
  GArray *retval;
 | 
			
		||||
  int n_keycodes;
 | 
			
		||||
  int keycode;
 | 
			
		||||
 | 
			
		||||
  retval = g_array_new (FALSE, FALSE, sizeof (int));
 | 
			
		||||
 | 
			
		||||
  keycode = display->min_keycode;
 | 
			
		||||
  while (keycode <= display->max_keycode)
 | 
			
		||||
    {
 | 
			
		||||
      const KeySym *syms = display->keymap + (keycode - display->min_keycode) * display->keysyms_per_keycode;
 | 
			
		||||
      int i = 0;
 | 
			
		||||
 | 
			
		||||
      while (i < display->keysyms_per_keycode)
 | 
			
		||||
        {
 | 
			
		||||
          if (syms[i] == (unsigned int)keysym)
 | 
			
		||||
            g_array_append_val (retval, keycode);
 | 
			
		||||
 | 
			
		||||
          ++i;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      ++keycode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  n_keycodes = retval->len;
 | 
			
		||||
  *keycodes = (int*) g_array_free (retval, n_keycodes == 0 ? TRUE : FALSE);
 | 
			
		||||
 | 
			
		||||
  return n_keycodes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
reload_iso_next_group_combos (MetaDisplay *display)
 | 
			
		||||
{
 | 
			
		||||
  const char *iso_next_group_option;
 | 
			
		||||
  MetaKeyCombo *combos;
 | 
			
		||||
  int *keycodes;
 | 
			
		||||
  int n_keycodes;
 | 
			
		||||
  int n_combos;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&display->iso_next_group_combos, g_free);
 | 
			
		||||
  display->n_iso_next_group_combos = 0;
 | 
			
		||||
 | 
			
		||||
  iso_next_group_option = meta_prefs_get_iso_next_group_option ();
 | 
			
		||||
  if (iso_next_group_option == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  n_keycodes = get_keycodes_for_keysym (display, XK_ISO_Next_Group, &keycodes);
 | 
			
		||||
 | 
			
		||||
  if (g_str_equal (iso_next_group_option, "toggle") ||
 | 
			
		||||
      g_str_equal (iso_next_group_option, "lalt_toggle") ||
 | 
			
		||||
      g_str_equal (iso_next_group_option, "lwin_toggle") ||
 | 
			
		||||
      g_str_equal (iso_next_group_option, "rwin_toggle") ||
 | 
			
		||||
      g_str_equal (iso_next_group_option, "lshift_toggle") ||
 | 
			
		||||
      g_str_equal (iso_next_group_option, "rshift_toggle") ||
 | 
			
		||||
      g_str_equal (iso_next_group_option, "lctrl_toggle") ||
 | 
			
		||||
      g_str_equal (iso_next_group_option, "rctrl_toggle") ||
 | 
			
		||||
      g_str_equal (iso_next_group_option, "sclk_toggle") ||
 | 
			
		||||
      g_str_equal (iso_next_group_option, "menu_toggle") ||
 | 
			
		||||
      g_str_equal (iso_next_group_option, "caps_toggle"))
 | 
			
		||||
    {
 | 
			
		||||
      n_combos = n_keycodes;
 | 
			
		||||
      combos = g_new (MetaKeyCombo, n_combos);
 | 
			
		||||
 | 
			
		||||
      for (i = 0; i < n_keycodes; ++i)
 | 
			
		||||
        {
 | 
			
		||||
          combos[i].keysym = XK_ISO_Next_Group;
 | 
			
		||||
          combos[i].keycode = keycodes[i];
 | 
			
		||||
          combos[i].modifiers = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else if (g_str_equal (iso_next_group_option, "shift_caps_toggle") ||
 | 
			
		||||
           g_str_equal (iso_next_group_option, "shifts_toggle"))
 | 
			
		||||
    {
 | 
			
		||||
      n_combos = n_keycodes;
 | 
			
		||||
      combos = g_new (MetaKeyCombo, n_combos);
 | 
			
		||||
 | 
			
		||||
      for (i = 0; i < n_keycodes; ++i)
 | 
			
		||||
        {
 | 
			
		||||
          combos[i].keysym = XK_ISO_Next_Group;
 | 
			
		||||
          combos[i].keycode = keycodes[i];
 | 
			
		||||
          combos[i].modifiers = ShiftMask;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else if (g_str_equal (iso_next_group_option, "alt_caps_toggle") ||
 | 
			
		||||
           g_str_equal (iso_next_group_option, "alt_space_toggle"))
 | 
			
		||||
    {
 | 
			
		||||
      n_combos = n_keycodes;
 | 
			
		||||
      combos = g_new (MetaKeyCombo, n_combos);
 | 
			
		||||
 | 
			
		||||
      for (i = 0; i < n_keycodes; ++i)
 | 
			
		||||
        {
 | 
			
		||||
          combos[i].keysym = XK_ISO_Next_Group;
 | 
			
		||||
          combos[i].keycode = keycodes[i];
 | 
			
		||||
          combos[i].modifiers = Mod1Mask;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else if (g_str_equal (iso_next_group_option, "ctrl_shift_toggle") ||
 | 
			
		||||
           g_str_equal (iso_next_group_option, "lctrl_lshift_toggle") ||
 | 
			
		||||
           g_str_equal (iso_next_group_option, "rctrl_rshift_toggle"))
 | 
			
		||||
    {
 | 
			
		||||
      n_combos = n_keycodes * 2;
 | 
			
		||||
      combos = g_new (MetaKeyCombo, n_combos);
 | 
			
		||||
 | 
			
		||||
      for (i = 0; i < n_keycodes; ++i)
 | 
			
		||||
        {
 | 
			
		||||
          combos[i].keysym = XK_ISO_Next_Group;
 | 
			
		||||
          combos[i].keycode = keycodes[i];
 | 
			
		||||
          combos[i].modifiers = ShiftMask;
 | 
			
		||||
 | 
			
		||||
          combos[i + n_keycodes].keysym = XK_ISO_Next_Group;
 | 
			
		||||
          combos[i + n_keycodes].keycode = keycodes[i];
 | 
			
		||||
          combos[i + n_keycodes].modifiers = ControlMask;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else if (g_str_equal (iso_next_group_option, "ctrl_alt_toggle"))
 | 
			
		||||
    {
 | 
			
		||||
      n_combos = n_keycodes * 2;
 | 
			
		||||
      combos = g_new (MetaKeyCombo, n_combos);
 | 
			
		||||
 | 
			
		||||
      for (i = 0; i < n_keycodes; ++i)
 | 
			
		||||
        {
 | 
			
		||||
          combos[i].keysym = XK_ISO_Next_Group;
 | 
			
		||||
          combos[i].keycode = keycodes[i];
 | 
			
		||||
          combos[i].modifiers = Mod1Mask;
 | 
			
		||||
 | 
			
		||||
          combos[i + n_keycodes].keysym = XK_ISO_Next_Group;
 | 
			
		||||
          combos[i + n_keycodes].keycode = keycodes[i];
 | 
			
		||||
          combos[i + n_keycodes].modifiers = ControlMask;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else if (g_str_equal (iso_next_group_option, "alt_shift_toggle") ||
 | 
			
		||||
           g_str_equal (iso_next_group_option, "lalt_lshift_toggle"))
 | 
			
		||||
    {
 | 
			
		||||
      n_combos = n_keycodes * 2;
 | 
			
		||||
      combos = g_new (MetaKeyCombo, n_combos);
 | 
			
		||||
 | 
			
		||||
      for (i = 0; i < n_keycodes; ++i)
 | 
			
		||||
        {
 | 
			
		||||
          combos[i].keysym = XK_ISO_Next_Group;
 | 
			
		||||
          combos[i].keycode = keycodes[i];
 | 
			
		||||
          combos[i].modifiers = Mod1Mask;
 | 
			
		||||
 | 
			
		||||
          combos[i + n_keycodes].keysym = XK_ISO_Next_Group;
 | 
			
		||||
          combos[i + n_keycodes].keycode = keycodes[i];
 | 
			
		||||
          combos[i + n_keycodes].modifiers = ShiftMask;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      n_combos = 0;
 | 
			
		||||
      combos = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_free (keycodes);
 | 
			
		||||
 | 
			
		||||
  display->n_iso_next_group_combos = n_combos;
 | 
			
		||||
  display->iso_next_group_combos = combos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static guint
 | 
			
		||||
keysym_to_keycode (MetaDisplay *display,
 | 
			
		||||
                   guint        keysym)
 | 
			
		||||
@@ -328,6 +494,8 @@ reload_keycodes (MetaDisplay *display)
 | 
			
		||||
      display->overlay_key_combo.keycode = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  reload_iso_next_group_combos (display);
 | 
			
		||||
 | 
			
		||||
  if (display->key_bindings)
 | 
			
		||||
    {
 | 
			
		||||
      int i;
 | 
			
		||||
@@ -1026,6 +1194,22 @@ meta_screen_change_keygrabs (MetaScreen *screen,
 | 
			
		||||
                         display->overlay_key_combo.keycode,
 | 
			
		||||
                         display->overlay_key_combo.modifiers);
 | 
			
		||||
 | 
			
		||||
  if (display->iso_next_group_combos)
 | 
			
		||||
    {
 | 
			
		||||
      int i = 0;
 | 
			
		||||
      while (i < display->n_iso_next_group_combos)
 | 
			
		||||
        {
 | 
			
		||||
          if (display->iso_next_group_combos[i].keycode != 0)
 | 
			
		||||
            {
 | 
			
		||||
              meta_change_keygrab (display, screen->xroot, grab,
 | 
			
		||||
                                   display->iso_next_group_combos[i].keysym,
 | 
			
		||||
                                   display->iso_next_group_combos[i].keycode,
 | 
			
		||||
                                   display->iso_next_group_combos[i].modifiers);
 | 
			
		||||
            }
 | 
			
		||||
          ++i;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  change_binding_keygrabs (screen->display->key_bindings,
 | 
			
		||||
                           screen->display->n_key_bindings,
 | 
			
		||||
                           screen->display, screen->xroot,
 | 
			
		||||
@@ -1264,7 +1448,8 @@ grab_status_to_string (int status)
 | 
			
		||||
static gboolean
 | 
			
		||||
grab_keyboard (MetaDisplay *display,
 | 
			
		||||
               Window       xwindow,
 | 
			
		||||
               guint32      timestamp)
 | 
			
		||||
               guint32      timestamp,
 | 
			
		||||
               int          grab_mode)
 | 
			
		||||
{
 | 
			
		||||
  int result;
 | 
			
		||||
  int grab_status;
 | 
			
		||||
@@ -1280,13 +1465,22 @@ grab_keyboard (MetaDisplay *display,
 | 
			
		||||
   */
 | 
			
		||||
  meta_error_trap_push_with_return (display);
 | 
			
		||||
 | 
			
		||||
  /* Strictly, we only need to set grab_mode on the keyboard device
 | 
			
		||||
   * while the pointer should always be XIGrabModeAsync. Unfortunately
 | 
			
		||||
   * there is a bug in the X server, only fixed (link below) in 1.15,
 | 
			
		||||
   * which swaps these arguments for keyboard devices. As such, we set
 | 
			
		||||
   * both the device and the paired device mode which works around
 | 
			
		||||
   * that bug and also works on fixed X servers.
 | 
			
		||||
   *
 | 
			
		||||
   * http://cgit.freedesktop.org/xorg/xserver/commit/?id=9003399708936481083424b4ff8f18a16b88b7b3
 | 
			
		||||
   */
 | 
			
		||||
  grab_status = XIGrabDevice (display->xdisplay,
 | 
			
		||||
                              META_VIRTUAL_CORE_KEYBOARD_ID,
 | 
			
		||||
                              xwindow,
 | 
			
		||||
                              timestamp,
 | 
			
		||||
                              None,
 | 
			
		||||
                              XIGrabModeAsync, XIGrabModeAsync,
 | 
			
		||||
                              True, /* owner_events */
 | 
			
		||||
                              grab_mode, grab_mode,
 | 
			
		||||
                              False, /* owner_events */
 | 
			
		||||
                              &mask);
 | 
			
		||||
 | 
			
		||||
  if (grab_status != Success)
 | 
			
		||||
@@ -1339,7 +1533,7 @@ meta_screen_grab_all_keys (MetaScreen *screen, guint32 timestamp)
 | 
			
		||||
 | 
			
		||||
  meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
              "Grabbing all keys on RootWindow\n");
 | 
			
		||||
  retval = grab_keyboard (screen->display, screen->xroot, timestamp);
 | 
			
		||||
  retval = grab_keyboard (screen->display, screen->xroot, timestamp, XIGrabModeAsync);
 | 
			
		||||
  if (retval)
 | 
			
		||||
    {
 | 
			
		||||
      screen->all_keys_grabbed = TRUE;
 | 
			
		||||
@@ -1392,7 +1586,7 @@ meta_window_grab_all_keys (MetaWindow  *window,
 | 
			
		||||
 | 
			
		||||
  meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
              "Grabbing all keys on window %s\n", window->desc);
 | 
			
		||||
  retval = grab_keyboard (window->display, grabwindow, timestamp);
 | 
			
		||||
  retval = grab_keyboard (window->display, grabwindow, timestamp, XIGrabModeAsync);
 | 
			
		||||
  if (retval)
 | 
			
		||||
    {
 | 
			
		||||
      window->keys_grabbed = FALSE;
 | 
			
		||||
@@ -1419,6 +1613,32 @@ meta_window_ungrab_all_keys (MetaWindow *window, guint32 timestamp)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_display_freeze_keyboard (MetaDisplay *display, Window window, guint32 timestamp)
 | 
			
		||||
{
 | 
			
		||||
  grab_keyboard (display, window, timestamp, XIGrabModeSync);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_display_ungrab_keyboard (MetaDisplay *display, guint32 timestamp)
 | 
			
		||||
{
 | 
			
		||||
  ungrab_keyboard (display, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_display_unfreeze_keyboard (MetaDisplay *display, guint32 timestamp)
 | 
			
		||||
{
 | 
			
		||||
  meta_error_trap_push (display);
 | 
			
		||||
  XIAllowEvents (display->xdisplay, META_VIRTUAL_CORE_KEYBOARD_ID,
 | 
			
		||||
                 XIAsyncDevice, timestamp);
 | 
			
		||||
  /* We shouldn't need to unfreeze the pointer device here, however we
 | 
			
		||||
   * have to, due to the workaround we do in grab_keyboard().
 | 
			
		||||
   */
 | 
			
		||||
  XIAllowEvents (display->xdisplay, META_VIRTUAL_CORE_POINTER_ID,
 | 
			
		||||
                 XIAsyncDevice, timestamp);
 | 
			
		||||
  meta_error_trap_pop (display);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
is_modifier (MetaDisplay *display,
 | 
			
		||||
             unsigned int keycode)
 | 
			
		||||
@@ -1765,6 +1985,41 @@ process_overlay_key (MetaDisplay *display,
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
process_iso_next_group (MetaDisplay *display,
 | 
			
		||||
                        MetaScreen *screen,
 | 
			
		||||
                        XIDeviceEvent *event,
 | 
			
		||||
                        KeySym keysym)
 | 
			
		||||
{
 | 
			
		||||
  gboolean activate;
 | 
			
		||||
  unsigned int mods;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  if (event->evtype != XI_KeyPress)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  activate = FALSE;
 | 
			
		||||
  mods = (event->mods.effective & 0xff & ~(display->ignored_modifier_mask));
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < display->n_iso_next_group_combos; ++i)
 | 
			
		||||
    {
 | 
			
		||||
      if (event->detail == (int)display->iso_next_group_combos[i].keycode &&
 | 
			
		||||
          mods == display->iso_next_group_combos[i].modifiers)
 | 
			
		||||
        {
 | 
			
		||||
          /* If the signal handler returns TRUE the keyboard will
 | 
			
		||||
             remain frozen. It's the signal handler's responsibility
 | 
			
		||||
             to unfreeze it. */
 | 
			
		||||
          if (!meta_display_modifiers_accelerator_activate (display))
 | 
			
		||||
            XIAllowEvents (display->xdisplay, event->deviceid,
 | 
			
		||||
                           XIAsyncDevice, event->time);
 | 
			
		||||
          activate = TRUE;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return activate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Handle a key event. May be called recursively: some key events cause
 | 
			
		||||
 * grabs to be ended and then need to be processed again in their own
 | 
			
		||||
 * right. This cannot cause infinite recursion because we never call
 | 
			
		||||
@@ -1839,6 +2094,10 @@ meta_display_process_key_event (MetaDisplay   *display,
 | 
			
		||||
      handled = process_overlay_key (display, screen, event, keysym);
 | 
			
		||||
      if (handled)
 | 
			
		||||
        return TRUE;
 | 
			
		||||
 | 
			
		||||
      handled = process_iso_next_group (display, screen, event, keysym);
 | 
			
		||||
      if (handled)
 | 
			
		||||
        return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  XIAllowEvents (display->xdisplay, event->deviceid,
 | 
			
		||||
@@ -4532,6 +4791,12 @@ meta_display_init_keys (MetaDisplay *display)
 | 
			
		||||
 | 
			
		||||
  g_hash_table_insert (key_handlers, g_strdup ("overlay-key"), handler);
 | 
			
		||||
 | 
			
		||||
  handler = g_new0 (MetaKeyHandler, 1);
 | 
			
		||||
  handler->name = g_strdup ("iso-next-group");
 | 
			
		||||
  handler->flags = META_KEY_BINDING_BUILTIN;
 | 
			
		||||
 | 
			
		||||
  g_hash_table_insert (key_handlers, g_strdup ("iso-next-group"), handler);
 | 
			
		||||
 | 
			
		||||
  handler = g_new0 (MetaKeyHandler, 1);
 | 
			
		||||
  handler->name = g_strdup ("external-grab");
 | 
			
		||||
  handler->func = handle_external_grab;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										279
									
								
								src/core/prefs.c
									
									
									
									
									
								
							
							
						
						
									
										279
									
								
								src/core/prefs.c
									
									
									
									
									
								
							@@ -55,6 +55,7 @@
 | 
			
		||||
#define KEY_GNOME_ANIMATIONS "enable-animations"
 | 
			
		||||
#define KEY_GNOME_CURSOR_THEME "cursor-theme"
 | 
			
		||||
#define KEY_GNOME_CURSOR_SIZE "cursor-size"
 | 
			
		||||
#define KEY_XKB_OPTIONS "xkb-options"
 | 
			
		||||
 | 
			
		||||
#define KEY_OVERLAY_KEY "overlay-key"
 | 
			
		||||
#define KEY_WORKSPACES_ONLY_ON_PRIMARY "workspaces-only-on-primary"
 | 
			
		||||
@@ -65,6 +66,7 @@
 | 
			
		||||
#define SCHEMA_GENERAL         "org.gnome.desktop.wm.preferences"
 | 
			
		||||
#define SCHEMA_MUTTER          "org.gnome.mutter"
 | 
			
		||||
#define SCHEMA_INTERFACE       "org.gnome.desktop.interface"
 | 
			
		||||
#define SCHEMA_INPUT_SOURCES   "org.gnome.desktop.input-sources"
 | 
			
		||||
 | 
			
		||||
#define SETTINGS(s) g_hash_table_lookup (settings_schemas, (s))
 | 
			
		||||
 | 
			
		||||
@@ -115,6 +117,7 @@ static gboolean workspaces_only_on_primary = FALSE;
 | 
			
		||||
 | 
			
		||||
static gboolean no_tab_popup = FALSE;
 | 
			
		||||
 | 
			
		||||
static char *iso_next_group_option = NULL;
 | 
			
		||||
 | 
			
		||||
static void handle_preference_update_enum (GSettings *settings,
 | 
			
		||||
                                           gchar     *key);
 | 
			
		||||
@@ -122,7 +125,6 @@ static gboolean update_binding         (MetaKeyPref *binding,
 | 
			
		||||
                                        gchar      **strokes);
 | 
			
		||||
static gboolean update_key_binding     (const char  *key,
 | 
			
		||||
                                        gchar      **strokes);
 | 
			
		||||
static gboolean update_workspace_names (void);
 | 
			
		||||
 | 
			
		||||
static void settings_changed (GSettings      *settings,
 | 
			
		||||
                              gchar          *key,
 | 
			
		||||
@@ -140,11 +142,11 @@ static gboolean theme_name_handler (GVariant*, gpointer*, gpointer);
 | 
			
		||||
static gboolean mouse_button_mods_handler (GVariant*, gpointer*, gpointer);
 | 
			
		||||
static gboolean button_layout_handler (GVariant*, gpointer*, gpointer);
 | 
			
		||||
static gboolean overlay_key_handler (GVariant*, gpointer*, gpointer);
 | 
			
		||||
static gboolean iso_next_group_handler (GVariant*, gpointer*, gpointer);
 | 
			
		||||
 | 
			
		||||
static void     do_override               (char *key, char *schema);
 | 
			
		||||
 | 
			
		||||
static void     init_bindings             (void);
 | 
			
		||||
static void     init_workspace_names      (void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
@@ -198,6 +200,13 @@ typedef struct
 | 
			
		||||
  gchar **target;
 | 
			
		||||
} MetaStringPreference;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  MetaBasePreference base;
 | 
			
		||||
  GSettingsGetMapping handler;
 | 
			
		||||
  gchar ***target;
 | 
			
		||||
} MetaStringArrayPreference;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  MetaBasePreference base;
 | 
			
		||||
@@ -436,6 +445,27 @@ static MetaStringPreference preferences_string[] =
 | 
			
		||||
    { { NULL, 0, 0 }, NULL },
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
static MetaStringArrayPreference preferences_string_array[] =
 | 
			
		||||
  {
 | 
			
		||||
    {
 | 
			
		||||
      { KEY_WORKSPACE_NAMES,
 | 
			
		||||
        SCHEMA_GENERAL,
 | 
			
		||||
        META_PREF_KEYBINDINGS,
 | 
			
		||||
      },
 | 
			
		||||
      NULL,
 | 
			
		||||
      &workspace_names,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      { KEY_XKB_OPTIONS,
 | 
			
		||||
        SCHEMA_INPUT_SOURCES,
 | 
			
		||||
        META_PREF_KEYBINDINGS,
 | 
			
		||||
      },
 | 
			
		||||
      iso_next_group_handler,
 | 
			
		||||
      NULL,
 | 
			
		||||
    },
 | 
			
		||||
    { { NULL, 0, 0 }, NULL },
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
static MetaIntPreference preferences_int[] =
 | 
			
		||||
  {
 | 
			
		||||
    {
 | 
			
		||||
@@ -555,6 +585,42 @@ handle_preference_init_string (void)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_preference_init_string_array (void)
 | 
			
		||||
{
 | 
			
		||||
  MetaStringArrayPreference *cursor = preferences_string_array;
 | 
			
		||||
 | 
			
		||||
  while (cursor->base.key != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      char **value;
 | 
			
		||||
 | 
			
		||||
      /* Complex keys have a mapping function to check validity */
 | 
			
		||||
      if (cursor->handler)
 | 
			
		||||
        {
 | 
			
		||||
          if (cursor->target)
 | 
			
		||||
            meta_bug ("%s has both a target and a handler\n", cursor->base.key);
 | 
			
		||||
 | 
			
		||||
          g_settings_get_mapped (SETTINGS (cursor->base.schema),
 | 
			
		||||
                                 cursor->base.key, cursor->handler, NULL);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          if (!cursor->target)
 | 
			
		||||
            meta_bug ("%s must have handler or target\n", cursor->base.key);
 | 
			
		||||
 | 
			
		||||
          if (*(cursor->target))
 | 
			
		||||
            g_strfreev (*(cursor->target));
 | 
			
		||||
 | 
			
		||||
          value = g_settings_get_strv (SETTINGS (cursor->base.schema),
 | 
			
		||||
                                       cursor->base.key);
 | 
			
		||||
 | 
			
		||||
          *(cursor->target) = value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      ++cursor;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_preference_init_int (void)
 | 
			
		||||
{
 | 
			
		||||
@@ -673,6 +739,56 @@ handle_preference_update_string (GSettings *settings,
 | 
			
		||||
    queue_changed (cursor->base.pref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_preference_update_string_array (GSettings *settings,
 | 
			
		||||
                                       gchar *key)
 | 
			
		||||
{
 | 
			
		||||
  MetaStringArrayPreference *cursor = preferences_string_array;
 | 
			
		||||
  gboolean inform_listeners = FALSE;
 | 
			
		||||
 | 
			
		||||
  while (cursor->base.key != NULL && strcmp (key, cursor->base.key) != 0)
 | 
			
		||||
    ++cursor;
 | 
			
		||||
 | 
			
		||||
  if (cursor->base.key==NULL)
 | 
			
		||||
    /* Didn't recognise that key. */
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* Complex keys have a mapping function to check validity */
 | 
			
		||||
  if (cursor->handler)
 | 
			
		||||
    {
 | 
			
		||||
      if (cursor->target)
 | 
			
		||||
        meta_bug ("%s has both a target and a handler\n", cursor->base.key);
 | 
			
		||||
 | 
			
		||||
      g_settings_get_mapped (SETTINGS (cursor->base.schema),
 | 
			
		||||
                             cursor->base.key, cursor->handler, NULL);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      char **values, **previous;
 | 
			
		||||
      int n_values, n_previous, i;
 | 
			
		||||
 | 
			
		||||
      if (!cursor->target)
 | 
			
		||||
        meta_bug ("%s must have handler or target\n", cursor->base.key);
 | 
			
		||||
 | 
			
		||||
      values = g_settings_get_strv (SETTINGS (cursor->base.schema),
 | 
			
		||||
                                    cursor->base.key);
 | 
			
		||||
      n_values = g_strv_length (values);
 | 
			
		||||
      previous = *(cursor->target);
 | 
			
		||||
      n_previous = previous ? g_strv_length (previous) : 0;
 | 
			
		||||
 | 
			
		||||
      inform_listeners = n_previous != n_values;
 | 
			
		||||
      for (i = 0; i < n_values && !inform_listeners; i++)
 | 
			
		||||
        inform_listeners = g_strcmp0 (values[i], previous[i]) != 0;
 | 
			
		||||
 | 
			
		||||
      if (*(cursor->target))
 | 
			
		||||
        g_strfreev (*(cursor->target));
 | 
			
		||||
      *(cursor->target) = values;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (inform_listeners)
 | 
			
		||||
    queue_changed (cursor->base.pref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_preference_update_int (GSettings *settings,
 | 
			
		||||
                              gchar *key)
 | 
			
		||||
@@ -857,6 +973,11 @@ meta_prefs_init (void)
 | 
			
		||||
                    G_CALLBACK (settings_changed), NULL);
 | 
			
		||||
  g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INTERFACE), settings);
 | 
			
		||||
 | 
			
		||||
  settings = g_settings_new (SCHEMA_INPUT_SOURCES);
 | 
			
		||||
  g_signal_connect (settings, "changed::" KEY_XKB_OPTIONS,
 | 
			
		||||
                    G_CALLBACK (settings_changed), NULL);
 | 
			
		||||
  g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INPUT_SOURCES), settings);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  for (tmp = overridden_keys; tmp; tmp = tmp->next)
 | 
			
		||||
    {
 | 
			
		||||
@@ -869,10 +990,10 @@ meta_prefs_init (void)
 | 
			
		||||
  handle_preference_init_enum ();
 | 
			
		||||
  handle_preference_init_bool ();
 | 
			
		||||
  handle_preference_init_string ();
 | 
			
		||||
  handle_preference_init_string_array ();
 | 
			
		||||
  handle_preference_init_int ();
 | 
			
		||||
 | 
			
		||||
  init_bindings ();
 | 
			
		||||
  init_workspace_names ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
@@ -1020,14 +1141,6 @@ settings_changed (GSettings *settings,
 | 
			
		||||
  MetaEnumPreference *cursor;
 | 
			
		||||
  gboolean found_enum;
 | 
			
		||||
 | 
			
		||||
  /* String array, handled separately */
 | 
			
		||||
  if (strcmp (key, KEY_WORKSPACE_NAMES) == 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (update_workspace_names ())
 | 
			
		||||
        queue_changed (META_PREF_WORKSPACE_NAMES);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  value = g_settings_get_value (settings, key);
 | 
			
		||||
  type = g_variant_get_type (value);
 | 
			
		||||
 | 
			
		||||
@@ -1035,6 +1148,8 @@ settings_changed (GSettings *settings,
 | 
			
		||||
    handle_preference_update_bool (settings, key);
 | 
			
		||||
  else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
 | 
			
		||||
    handle_preference_update_int (settings, key);
 | 
			
		||||
  else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING_ARRAY))
 | 
			
		||||
    handle_preference_update_string_array (settings, key);
 | 
			
		||||
  else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
 | 
			
		||||
    {
 | 
			
		||||
      cursor = preferences_enum;
 | 
			
		||||
@@ -1554,6 +1669,39 @@ overlay_key_handler (GVariant *value,
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
iso_next_group_handler (GVariant *value,
 | 
			
		||||
                        gpointer *result,
 | 
			
		||||
                        gpointer  data)
 | 
			
		||||
{
 | 
			
		||||
  const char **xkb_options, **p;
 | 
			
		||||
  const char *option = NULL;
 | 
			
		||||
  gboolean changed = FALSE;
 | 
			
		||||
 | 
			
		||||
  *result = NULL; /* ignored */
 | 
			
		||||
  xkb_options = g_variant_get_strv (value, NULL);
 | 
			
		||||
 | 
			
		||||
  for (p = xkb_options; p && *p; ++p)
 | 
			
		||||
    if (g_str_has_prefix (*p, "grp:"))
 | 
			
		||||
      {
 | 
			
		||||
        option = (*p + 4);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
  changed = (g_strcmp0 (option, iso_next_group_option) != 0);
 | 
			
		||||
 | 
			
		||||
  if (changed)
 | 
			
		||||
    {
 | 
			
		||||
      g_free (iso_next_group_option);
 | 
			
		||||
      iso_next_group_option = g_strdup (option);
 | 
			
		||||
      queue_changed (META_PREF_KEYBINDINGS);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_free (xkb_options);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const PangoFontDescription*
 | 
			
		||||
meta_prefs_get_titlebar_font (void)
 | 
			
		||||
{
 | 
			
		||||
@@ -1708,12 +1856,13 @@ meta_prefs_set_num_workspaces (int n_workspaces)
 | 
			
		||||
{
 | 
			
		||||
  MetaBasePreference *pref;
 | 
			
		||||
 | 
			
		||||
  find_pref (preferences_int, sizeof(MetaIntPreference),
 | 
			
		||||
             KEY_NUM_WORKSPACES, &pref);
 | 
			
		||||
 | 
			
		||||
  g_settings_set_int (SETTINGS (pref->schema),
 | 
			
		||||
                      KEY_NUM_WORKSPACES,
 | 
			
		||||
                      n_workspaces);
 | 
			
		||||
  if (find_pref (preferences_int, sizeof(MetaIntPreference),
 | 
			
		||||
                 KEY_NUM_WORKSPACES, &pref))
 | 
			
		||||
    {
 | 
			
		||||
      g_settings_set_int (SETTINGS (pref->schema),
 | 
			
		||||
                          KEY_NUM_WORKSPACES,
 | 
			
		||||
                          n_workspaces);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GHashTable *key_bindings;
 | 
			
		||||
@@ -1747,20 +1896,15 @@ init_bindings (void)
 | 
			
		||||
  g_hash_table_insert (key_bindings, g_strdup ("overlay-key"), pref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
init_workspace_names (void)
 | 
			
		||||
{
 | 
			
		||||
  update_workspace_names ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
update_binding (MetaKeyPref *binding,
 | 
			
		||||
                gchar      **strokes)
 | 
			
		||||
{
 | 
			
		||||
  GSList *old_bindings, *a, *b;
 | 
			
		||||
  gboolean changed;
 | 
			
		||||
  unsigned int keysym;
 | 
			
		||||
  unsigned int keycode;
 | 
			
		||||
  MetaVirtualModifier mods;
 | 
			
		||||
  gboolean changed = FALSE;
 | 
			
		||||
  MetaKeyCombo *combo;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
@@ -1768,13 +1912,9 @@ update_binding (MetaKeyPref *binding,
 | 
			
		||||
              "Binding \"%s\" has new GSettings value\n",
 | 
			
		||||
              binding->name);
 | 
			
		||||
 | 
			
		||||
  /* Okay, so, we're about to provide a new list of key combos for this
 | 
			
		||||
   * action. Delete any pre-existing list.
 | 
			
		||||
   */
 | 
			
		||||
  g_slist_foreach (binding->bindings, (GFunc) g_free, NULL);
 | 
			
		||||
  g_slist_free (binding->bindings);
 | 
			
		||||
  old_bindings = binding->bindings;
 | 
			
		||||
  binding->bindings = NULL;
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  for (i = 0; strokes && strokes[i]; i++)
 | 
			
		||||
    {
 | 
			
		||||
      keysym = 0;
 | 
			
		||||
@@ -1809,8 +1949,6 @@ update_binding (MetaKeyPref *binding,
 | 
			
		||||
           * Changing the key in response to a modification could lead to cyclic calls. */
 | 
			
		||||
          continue;
 | 
			
		||||
        }
 | 
			
		||||
  
 | 
			
		||||
      changed = TRUE;
 | 
			
		||||
 | 
			
		||||
      combo = g_malloc0 (sizeof (MetaKeyCombo));
 | 
			
		||||
      combo->keysym = keysym;
 | 
			
		||||
@@ -1825,6 +1963,34 @@ update_binding (MetaKeyPref *binding,
 | 
			
		||||
 | 
			
		||||
  binding->bindings = g_slist_reverse (binding->bindings);
 | 
			
		||||
 | 
			
		||||
  a = old_bindings;
 | 
			
		||||
  b = binding->bindings;
 | 
			
		||||
  while (TRUE)
 | 
			
		||||
    {
 | 
			
		||||
      if ((!a && b) || (a && !b))
 | 
			
		||||
        {
 | 
			
		||||
          changed = TRUE;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      else if (!a && !b)
 | 
			
		||||
        {
 | 
			
		||||
          changed = FALSE;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      else if (memcmp (a->data, b->data, sizeof (MetaKeyCombo)) != 0)
 | 
			
		||||
        {
 | 
			
		||||
          changed = TRUE;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          a = a->next;
 | 
			
		||||
          b = b->next;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_slist_free_full (old_bindings, g_free);
 | 
			
		||||
 | 
			
		||||
  return changed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1840,41 +2006,6 @@ update_key_binding (const char *key,
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
update_workspace_names (void)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  char **names;
 | 
			
		||||
  int n_workspace_names, n_names;
 | 
			
		||||
  gboolean changed = FALSE;
 | 
			
		||||
 | 
			
		||||
  names = g_settings_get_strv (SETTINGS (SCHEMA_GENERAL), KEY_WORKSPACE_NAMES);
 | 
			
		||||
  n_names = g_strv_length (names);
 | 
			
		||||
  n_workspace_names = workspace_names ? g_strv_length (workspace_names) : 0;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_names; i++)
 | 
			
		||||
    if (n_workspace_names < i + 1 || !workspace_names[i] ||
 | 
			
		||||
        g_strcmp0 (names[i], workspace_names[i]) != 0)
 | 
			
		||||
      {
 | 
			
		||||
        changed = TRUE;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
  if (n_workspace_names != n_names)
 | 
			
		||||
    changed = TRUE;
 | 
			
		||||
 | 
			
		||||
  if (changed)
 | 
			
		||||
    {
 | 
			
		||||
      if (workspace_names)
 | 
			
		||||
        g_strfreev (workspace_names);
 | 
			
		||||
      workspace_names = names;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    g_strfreev (names);
 | 
			
		||||
 | 
			
		||||
  return changed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char*
 | 
			
		||||
meta_prefs_get_workspace_name (int i)
 | 
			
		||||
{
 | 
			
		||||
@@ -2074,6 +2205,12 @@ meta_prefs_get_overlay_binding (MetaKeyCombo *combo)
 | 
			
		||||
  *combo = overlay_key_combo;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *
 | 
			
		||||
meta_prefs_get_iso_next_group_option (void)
 | 
			
		||||
{
 | 
			
		||||
  return iso_next_group_option;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GDesktopTitlebarAction
 | 
			
		||||
meta_prefs_get_action_double_click_titlebar (void)
 | 
			
		||||
{
 | 
			
		||||
@@ -2216,9 +2353,11 @@ meta_prefs_set_no_tab_popup (gboolean whether)
 | 
			
		||||
{
 | 
			
		||||
  MetaBasePreference *pref;
 | 
			
		||||
 | 
			
		||||
  find_pref (preferences_bool, sizeof(MetaBoolPreference),
 | 
			
		||||
             KEY_NO_TAB_POPUP, &pref);
 | 
			
		||||
  g_settings_set_boolean (SETTINGS (pref->schema), KEY_NO_TAB_POPUP, whether);
 | 
			
		||||
  if (find_pref (preferences_bool, sizeof(MetaBoolPreference),
 | 
			
		||||
                 KEY_NO_TAB_POPUP, &pref))
 | 
			
		||||
    {
 | 
			
		||||
      g_settings_set_boolean (SETTINGS (pref->schema), KEY_NO_TAB_POPUP, whether);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
 
 | 
			
		||||
@@ -187,6 +187,9 @@ MetaWindow*   meta_screen_get_mouse_window     (MetaScreen                 *scre
 | 
			
		||||
                                                MetaWindow                 *not_this_one);
 | 
			
		||||
 | 
			
		||||
const MetaMonitorInfo* meta_screen_get_current_monitor_info   (MetaScreen    *screen);
 | 
			
		||||
const MetaMonitorInfo* meta_screen_get_current_monitor_info_for_pos   (MetaScreen    *screen,
 | 
			
		||||
                                                                       int x,
 | 
			
		||||
                                                                       int y);
 | 
			
		||||
const MetaMonitorInfo* meta_screen_get_monitor_for_rect   (MetaScreen    *screen,
 | 
			
		||||
                                                           MetaRectangle *rect);
 | 
			
		||||
const MetaMonitorInfo* meta_screen_get_monitor_for_window (MetaScreen    *screen,
 | 
			
		||||
 
 | 
			
		||||
@@ -2216,6 +2216,65 @@ meta_screen_get_current_monitor_info (MetaScreen *screen)
 | 
			
		||||
    return &screen->monitor_infos[monitor_index];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const MetaMonitorInfo*
 | 
			
		||||
meta_screen_get_current_monitor_info_for_pos (MetaScreen *screen,
 | 
			
		||||
                                              int x,
 | 
			
		||||
                                              int y)
 | 
			
		||||
{
 | 
			
		||||
    int monitor_index;
 | 
			
		||||
    monitor_index = meta_screen_get_current_monitor_for_pos (screen, x, y);
 | 
			
		||||
    return &screen->monitor_infos[monitor_index];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_screen_get_current_monitor_for_pos:
 | 
			
		||||
 * @screen: a #MetaScreen
 | 
			
		||||
 * @x: The x coordinate
 | 
			
		||||
 * @y: The y coordinate
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the index of the monitor that contains the passed coordinates.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: a monitor index
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
meta_screen_get_current_monitor_for_pos (MetaScreen *screen,
 | 
			
		||||
                                         int x,
 | 
			
		||||
                                         int y)
 | 
			
		||||
{
 | 
			
		||||
  if (screen->n_monitor_infos == 1)
 | 
			
		||||
    return 0;
 | 
			
		||||
  else if (screen->display->monitor_cache_invalidated)
 | 
			
		||||
    {
 | 
			
		||||
      int i;
 | 
			
		||||
      MetaRectangle pointer_position;
 | 
			
		||||
      pointer_position.x = x;
 | 
			
		||||
      pointer_position.y = y;
 | 
			
		||||
      pointer_position.width = pointer_position.height = 1;
 | 
			
		||||
 | 
			
		||||
      screen->display->monitor_cache_invalidated = FALSE;
 | 
			
		||||
      screen->last_monitor_index = 0;
 | 
			
		||||
 | 
			
		||||
      for (i = 0; i < screen->n_monitor_infos; i++)
 | 
			
		||||
        {
 | 
			
		||||
          if (meta_rectangle_contains_rect (&screen->monitor_infos[i].rect,
 | 
			
		||||
                                            &pointer_position))
 | 
			
		||||
            {
 | 
			
		||||
              screen->last_monitor_index = i;
 | 
			
		||||
              break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      meta_topic (META_DEBUG_XINERAMA,
 | 
			
		||||
                  "Rechecked current monitor, now %d\n",
 | 
			
		||||
                  screen->last_monitor_index);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return screen->last_monitor_index;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_screen_get_current_monitor:
 | 
			
		||||
 * @screen: a #MetaScreen
 | 
			
		||||
@@ -2241,11 +2300,7 @@ meta_screen_get_current_monitor (MetaScreen *screen)
 | 
			
		||||
      XIButtonState buttons;
 | 
			
		||||
      XIModifierState mods;
 | 
			
		||||
      XIGroupState group;
 | 
			
		||||
      int i;
 | 
			
		||||
      MetaRectangle pointer_position;
 | 
			
		||||
 | 
			
		||||
      screen->display->monitor_cache_invalidated = FALSE;
 | 
			
		||||
      
 | 
			
		||||
      XIQueryPointer (screen->display->xdisplay,
 | 
			
		||||
                      META_VIRTUAL_CORE_POINTER_ID,
 | 
			
		||||
                      screen->xroot,
 | 
			
		||||
@@ -2260,24 +2315,7 @@ meta_screen_get_current_monitor (MetaScreen *screen)
 | 
			
		||||
                      &group);
 | 
			
		||||
      free (buttons.mask);
 | 
			
		||||
 | 
			
		||||
      pointer_position.x = root_x_return;
 | 
			
		||||
      pointer_position.y = root_y_return;
 | 
			
		||||
      pointer_position.width = pointer_position.height = 1;
 | 
			
		||||
 | 
			
		||||
      screen->last_monitor_index = 0;
 | 
			
		||||
      for (i = 0; i < screen->n_monitor_infos; i++)
 | 
			
		||||
        {
 | 
			
		||||
          if (meta_rectangle_contains_rect (&screen->monitor_infos[i].rect,
 | 
			
		||||
                                            &pointer_position))
 | 
			
		||||
            {
 | 
			
		||||
              screen->last_monitor_index = i;
 | 
			
		||||
              break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
      
 | 
			
		||||
      meta_topic (META_DEBUG_XINERAMA,
 | 
			
		||||
                  "Rechecked current monitor, now %d\n",
 | 
			
		||||
                  screen->last_monitor_index);
 | 
			
		||||
      meta_screen_get_current_monitor_for_pos (screen, root_x_return, root_y_return);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return screen->last_monitor_index;
 | 
			
		||||
@@ -3001,7 +3039,7 @@ meta_screen_resize (MetaScreen *screen,
 | 
			
		||||
 | 
			
		||||
  /* Fix up monitor for all windows on this screen */
 | 
			
		||||
  windows = meta_display_list_windows (screen->display,
 | 
			
		||||
                                       META_LIST_DEFAULT);
 | 
			
		||||
                                       META_LIST_INCLUDE_OVERRIDE_REDIRECT);
 | 
			
		||||
  for (tmp = windows; tmp != NULL; tmp = tmp->next)
 | 
			
		||||
    {
 | 
			
		||||
      MetaWindow *window = tmp->data;
 | 
			
		||||
 
 | 
			
		||||
@@ -145,6 +145,8 @@ static void meta_window_move_between_rects (MetaWindow          *window,
 | 
			
		||||
static void unmaximize_window_before_freeing (MetaWindow        *window);
 | 
			
		||||
static void unminimize_window_and_all_transient_parents (MetaWindow *window);
 | 
			
		||||
 | 
			
		||||
static void meta_window_update_monitor (MetaWindow *window);
 | 
			
		||||
 | 
			
		||||
/* Idle handlers for the three queues (run with meta_later_add()). The
 | 
			
		||||
 * "data" parameter in each case will be a GINT_TO_POINTER of the
 | 
			
		||||
 * index into the queue arrays to use.
 | 
			
		||||
@@ -253,6 +255,8 @@ meta_window_finalize (GObject *object)
 | 
			
		||||
  g_free (window->gtk_window_object_path);
 | 
			
		||||
  g_free (window->gtk_app_menu_object_path);
 | 
			
		||||
  g_free (window->gtk_menubar_object_path);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (meta_window_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -4786,6 +4790,12 @@ meta_window_update_for_monitors_changed (MetaWindow *window)
 | 
			
		||||
  if (window->type == META_WINDOW_DESKTOP)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (window->override_redirect)
 | 
			
		||||
    {
 | 
			
		||||
      meta_window_update_monitor (window);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  old = window->monitor;
 | 
			
		||||
 | 
			
		||||
  /* Start on primary */
 | 
			
		||||
@@ -6624,6 +6634,41 @@ meta_window_change_workspace_by_index (MetaWindow *window,
 | 
			
		||||
#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD    10
 | 
			
		||||
#define _NET_WM_MOVERESIZE_CANCEL           11
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
query_pressed_buttons (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  double x, y, query_root_x, query_root_y;
 | 
			
		||||
  Window root, child;
 | 
			
		||||
  XIButtonState buttons;
 | 
			
		||||
  XIModifierState mods;
 | 
			
		||||
  XIGroupState group;
 | 
			
		||||
  int button = 0;
 | 
			
		||||
 | 
			
		||||
  meta_error_trap_push (window->display);
 | 
			
		||||
  XIQueryPointer (window->display->xdisplay,
 | 
			
		||||
                  META_VIRTUAL_CORE_POINTER_ID,
 | 
			
		||||
                  window->xwindow,
 | 
			
		||||
                  &root, &child,
 | 
			
		||||
                  &query_root_x, &query_root_y,
 | 
			
		||||
                  &x, &y,
 | 
			
		||||
                  &buttons, &mods, &group);
 | 
			
		||||
 | 
			
		||||
  if (meta_error_trap_pop_with_return (window->display) != Success)
 | 
			
		||||
    goto out;
 | 
			
		||||
 | 
			
		||||
  if (XIMaskIsSet (buttons.mask, Button1))
 | 
			
		||||
    button |= 1 << 1;
 | 
			
		||||
  if (XIMaskIsSet (buttons.mask, Button2))
 | 
			
		||||
    button |= 1 << 2;
 | 
			
		||||
  if (XIMaskIsSet (buttons.mask, Button3))
 | 
			
		||||
    button |= 1 << 3;
 | 
			
		||||
 | 
			
		||||
  free (buttons.mask);
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  return button;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_window_client_message (MetaWindow *window,
 | 
			
		||||
                            XEvent     *event)
 | 
			
		||||
@@ -6982,56 +7027,58 @@ meta_window_client_message (MetaWindow *window,
 | 
			
		||||
                (op != META_GRAB_OP_MOVING &&
 | 
			
		||||
                 op != META_GRAB_OP_KEYBOARD_MOVING))))
 | 
			
		||||
        {
 | 
			
		||||
          /*
 | 
			
		||||
           * the button SHOULD already be included in the message
 | 
			
		||||
           */
 | 
			
		||||
          int button_mask;
 | 
			
		||||
 | 
			
		||||
          meta_topic (META_DEBUG_WINDOW_OPS,
 | 
			
		||||
                      "Beginning move/resize with button = %d\n", button);
 | 
			
		||||
          meta_display_begin_grab_op (window->display,
 | 
			
		||||
                                      window->screen,
 | 
			
		||||
                                      window,
 | 
			
		||||
                                      op,
 | 
			
		||||
                                      FALSE,
 | 
			
		||||
                                      frame_action,
 | 
			
		||||
                                      button, 0,
 | 
			
		||||
                                      timestamp,
 | 
			
		||||
                                      x_root,
 | 
			
		||||
                                      y_root);
 | 
			
		||||
 | 
			
		||||
          button_mask = query_pressed_buttons (window);
 | 
			
		||||
 | 
			
		||||
          if (button == 0)
 | 
			
		||||
            {
 | 
			
		||||
              double x, y, query_root_x, query_root_y;
 | 
			
		||||
              Window root, child;
 | 
			
		||||
              XIButtonState buttons;
 | 
			
		||||
              XIModifierState mods;
 | 
			
		||||
              XIGroupState group;
 | 
			
		||||
 | 
			
		||||
              /* The race conditions in this _NET_WM_MOVERESIZE thing
 | 
			
		||||
               * are mind-boggling
 | 
			
		||||
              /*
 | 
			
		||||
               * the button SHOULD already be included in the message
 | 
			
		||||
               */
 | 
			
		||||
              meta_error_trap_push (window->display);
 | 
			
		||||
              XIQueryPointer (window->display->xdisplay,
 | 
			
		||||
                              META_VIRTUAL_CORE_POINTER_ID,
 | 
			
		||||
                              window->xwindow,
 | 
			
		||||
                              &root, &child,
 | 
			
		||||
                              &query_root_x, &query_root_y,
 | 
			
		||||
                              &x, &y,
 | 
			
		||||
                              &buttons, &mods, &group);
 | 
			
		||||
              meta_error_trap_pop (window->display);
 | 
			
		||||
 | 
			
		||||
              if (XIMaskIsSet (buttons.mask, Button1))
 | 
			
		||||
              if ((button_mask & (1 << 1)) != 0)
 | 
			
		||||
                button = 1;
 | 
			
		||||
              else if (XIMaskIsSet (buttons.mask, Button2))
 | 
			
		||||
              else if ((button_mask & (1 << 2)) != 0)
 | 
			
		||||
                button = 2;
 | 
			
		||||
              else if (XIMaskIsSet (buttons.mask, Button3))
 | 
			
		||||
              else if ((button_mask & (1 << 3)) != 0)
 | 
			
		||||
                button = 3;
 | 
			
		||||
 | 
			
		||||
              if (button != 0)
 | 
			
		||||
                window->display->grab_button = button;
 | 
			
		||||
              else
 | 
			
		||||
                button = 0;
 | 
			
		||||
 | 
			
		||||
              free (buttons.mask);
 | 
			
		||||
                meta_display_end_grab_op (window->display,
 | 
			
		||||
                                          timestamp);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          if (button != 0)
 | 
			
		||||
          else
 | 
			
		||||
            {
 | 
			
		||||
              meta_topic (META_DEBUG_WINDOW_OPS,
 | 
			
		||||
                          "Beginning move/resize with button = %d\n", button);
 | 
			
		||||
              meta_display_begin_grab_op (window->display,
 | 
			
		||||
                                          window->screen,
 | 
			
		||||
                                          window,
 | 
			
		||||
                                          op,
 | 
			
		||||
                                          FALSE,
 | 
			
		||||
                                          frame_action,
 | 
			
		||||
                                          button, 0,
 | 
			
		||||
                                          timestamp,
 | 
			
		||||
                                          x_root,
 | 
			
		||||
                                          y_root);
 | 
			
		||||
              /* There is a potential race here. If the user presses and
 | 
			
		||||
               * releases their mouse button very fast, it's possible for
 | 
			
		||||
               * both the ButtonPress and ButtonRelease to be sent to the
 | 
			
		||||
               * client before it can get a chance to send _NET_WM_MOVERESIZE
 | 
			
		||||
               * to us. When that happens, we'll become stuck in a grab
 | 
			
		||||
               * state, as we haven't received a ButtonRelease to cancel the
 | 
			
		||||
               * grab.
 | 
			
		||||
               *
 | 
			
		||||
               * We can solve this by querying after we take the explicit
 | 
			
		||||
               * pointer grab -- if the button isn't pressed, we cancel the
 | 
			
		||||
               * drag immediately.
 | 
			
		||||
               */
 | 
			
		||||
 | 
			
		||||
              if ((button_mask & (1 << button)) == 0)
 | 
			
		||||
                meta_display_end_grab_op (window->display, timestamp);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -9007,7 +9054,7 @@ update_move (MetaWindow  *window,
 | 
			
		||||
       * refers to the monitor which contains the largest part of the window,
 | 
			
		||||
       * the latter to the one where the pointer is located.
 | 
			
		||||
       */
 | 
			
		||||
      monitor = meta_screen_get_current_monitor_info (window->screen);
 | 
			
		||||
      monitor = meta_screen_get_current_monitor_info_for_pos (window->screen, x, y);
 | 
			
		||||
      meta_window_get_work_area_for_monitor (window,
 | 
			
		||||
                                             monitor->number,
 | 
			
		||||
                                             &work_area);
 | 
			
		||||
 
 | 
			
		||||
@@ -187,4 +187,11 @@ void meta_display_unmanage_screen (MetaDisplay *display,
 | 
			
		||||
 | 
			
		||||
void meta_display_clear_mouse_mode (MetaDisplay *display);
 | 
			
		||||
 | 
			
		||||
void meta_display_freeze_keyboard (MetaDisplay *display,
 | 
			
		||||
                                   Window       window,
 | 
			
		||||
                                   guint32      timestamp);
 | 
			
		||||
void meta_display_ungrab_keyboard (MetaDisplay *display,
 | 
			
		||||
                                   guint32      timestamp);
 | 
			
		||||
void meta_display_unfreeze_keyboard (MetaDisplay *display,
 | 
			
		||||
                                     guint32      timestamp);
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -353,6 +353,7 @@ typedef enum _MetaKeyBindingAction
 | 
			
		||||
  META_KEYBINDING_ACTION_MOVE_TO_SIDE_W,
 | 
			
		||||
  META_KEYBINDING_ACTION_MOVE_TO_CENTER,
 | 
			
		||||
  META_KEYBINDING_ACTION_OVERLAY_KEY,
 | 
			
		||||
  META_KEYBINDING_ACTION_ISO_NEXT_GROUP,
 | 
			
		||||
 | 
			
		||||
  META_KEYBINDING_ACTION_LAST
 | 
			
		||||
} MetaKeyBindingAction;
 | 
			
		||||
@@ -442,6 +443,7 @@ void meta_prefs_get_window_binding (const char          *name,
 | 
			
		||||
                                    MetaVirtualModifier *modifiers);
 | 
			
		||||
 | 
			
		||||
void meta_prefs_get_overlay_binding (MetaKeyCombo *combo);
 | 
			
		||||
const char *meta_prefs_get_iso_next_group_option (void);
 | 
			
		||||
 | 
			
		||||
gboolean           meta_prefs_get_visual_bell      (void);
 | 
			
		||||
gboolean           meta_prefs_bell_is_audible      (void);
 | 
			
		||||
 
 | 
			
		||||
@@ -78,6 +78,9 @@ MetaWorkspace * meta_screen_get_active_workspace (MetaScreen *screen);
 | 
			
		||||
int  meta_screen_get_n_monitors       (MetaScreen    *screen);
 | 
			
		||||
int  meta_screen_get_primary_monitor  (MetaScreen    *screen);
 | 
			
		||||
int  meta_screen_get_current_monitor  (MetaScreen    *screen);
 | 
			
		||||
int  meta_screen_get_current_monitor_for_pos  (MetaScreen    *screen,
 | 
			
		||||
                                               int x,
 | 
			
		||||
                                               int y);
 | 
			
		||||
void meta_screen_get_monitor_geometry (MetaScreen    *screen,
 | 
			
		||||
                                       int            monitor,
 | 
			
		||||
                                       MetaRectangle *geometry);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user