Compare commits
	
		
			36 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | a5d3079c8a | ||
|   | 18a0c10aed | ||
|   | 8a35f8939d | ||
|   | 5b675fdd39 | ||
|   | 3aa295ba86 | ||
|   | 16629c289f | ||
|   | 4bf5e27c80 | ||
|   | f4ddff14b9 | ||
|   | 59908a01c1 | ||
|   | 6781709a75 | ||
|   | 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" | ||||
|   | ||||
							
								
								
									
										1282
									
								
								po/zh_CN.po
									
									
									
									
									
								
							
							
						
						
									
										1282
									
								
								po/zh_CN.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -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, | ||||
| @@ -1019,7 +1031,6 @@ meta_background_load_file_finish (MetaBackground  *self, | ||||
|                                   GAsyncResult    *result, | ||||
|                                   GError         **error) | ||||
| { | ||||
|   static CoglUserDataKey key; | ||||
|   GTask *task; | ||||
|   LoadFileTaskData *task_data; | ||||
|   CoglTexture *texture; | ||||
| @@ -1065,12 +1076,6 @@ meta_background_load_file_finish (MetaBackground  *self, | ||||
|       goto out; | ||||
|     } | ||||
|  | ||||
|   cogl_object_set_user_data (COGL_OBJECT (texture), | ||||
|                              &key, | ||||
|                              g_object_ref (pixbuf), | ||||
|                              (CoglUserDataDestroyCallback) | ||||
|                              g_object_unref); | ||||
|  | ||||
|   ensure_pipeline (self); | ||||
|   unset_texture (self); | ||||
|   set_style (self, task_data->style); | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -250,11 +250,30 @@ meta_window_group_paint (ClutterActor *actor) | ||||
|   g_list_free (children); | ||||
| } | ||||
|  | ||||
| /* Adapted from clutter_actor_update_default_paint_volume() */ | ||||
| static gboolean | ||||
| meta_window_group_get_paint_volume (ClutterActor       *actor, | ||||
| meta_window_group_get_paint_volume (ClutterActor       *self, | ||||
|                                     ClutterPaintVolume *volume) | ||||
| { | ||||
|   return clutter_paint_volume_set_from_allocation (volume, actor); | ||||
|   ClutterActorIter iter; | ||||
|   ClutterActor *child; | ||||
|  | ||||
|   clutter_actor_iter_init (&iter, self); | ||||
|   while (clutter_actor_iter_next (&iter, &child)) | ||||
|     { | ||||
|       const ClutterPaintVolume *child_volume; | ||||
|  | ||||
|       if (!CLUTTER_ACTOR_IS_MAPPED (child)) | ||||
|         continue; | ||||
|  | ||||
|       child_volume = clutter_actor_get_transformed_paint_volume (child, self); | ||||
|       if (child_volume == NULL) | ||||
|         return FALSE; | ||||
|  | ||||
|       clutter_paint_volume_union (volume, child_volume); | ||||
|     } | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -78,6 +78,7 @@ static void | ||||
| meta_workspace_finalize (GObject *object) | ||||
| { | ||||
|   /* Actual freeing done in meta_workspace_remove() for now */ | ||||
|   G_OBJECT_CLASS (meta_workspace_parent_class)->finalize (object); | ||||
| } | ||||
|  | ||||
| static void | ||||
|   | ||||
| @@ -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