diff -rupN a/dialogs/keyboard-settings/keyboard-dialog.glade b/dialogs/keyboard-settings/keyboard-dialog.glade --- a/dialogs/keyboard-settings/keyboard-dialog.glade 2012-04-28 20:48:30.000000000 +0000 +++ b/dialogs/keyboard-settings/keyboard-dialog.glade 2012-06-21 11:30:07.000000000 +0000 @@ -113,8 +113,8 @@ False end - - gtk-close + + gtk-help False True True @@ -125,11 +125,12 @@ False False 0 + True - - gtk-help + + gtk-close False True True @@ -140,7 +141,6 @@ False False 0 - True @@ -689,6 +689,92 @@ + + True + False + True + + + True + False + 0 + none + + + True + False + 6 + 12 + + + True + False + + + + + + + True + False + Change layout option + + + + + + + + False + True + 0 + + + + + True + False + 0 + none + + + True + False + 6 + 12 + + + True + False + + + + + + + True + False + Manage layout + + + + + + + + False + True + 1 + + + + + False + True + 2 + + + True False @@ -802,7 +888,7 @@ True True - 2 + 3 @@ -839,8 +925,8 @@ - button2 button1 + button2 diff -rupN a/dialogs/keyboard-settings/keyboard-dialog_ui.h b/dialogs/keyboard-settings/keyboard-dialog_ui.h --- a/dialogs/keyboard-settings/keyboard-dialog_ui.h 2012-04-28 20:48:40.000000000 +0000 +++ b/dialogs/keyboard-settings/keyboard-dialog_ui.h 2012-06-21 11:30:07.000000000 +0000 @@ -1,4 +1,4 @@ -/* automatically generated from keyboard-dialog.glade */ +/* automatically generated from keyboard-dialog1.glade */ #ifdef __SUNPRO_C #pragma align 4 (keyboard_dialog_ui) #endif @@ -70,70 +70,70 @@ static const char keyboard_dialog_ui[] = "ect class=\"GtkHButtonBox\" id=\"dialog-action_area1\">TrueFalse<" "property name=\"layout_style\">endgtk-closeFalsegtk-helpFalseTrueTrueTrueTrueFalse" "False0gtk-helpFalseTrueTrueTrueTr" - "ueFalseFalse0" - "TrueFalseTrueend0True" - "False66TrueTrueTru" - "eFalse126<" - "child>TrueFalse0none" - "TrueFals" - "e66186Restore num l_ock state on startupFalseTrueTrueFalseTrueTrueTrueFalseGeneralTrueFalseTrue0TrueFalse0" - "noneTrueFalse12TrueFals" - "e66_Ena" - "ble key repeatFalse" - "TrueTrueFalseWhen select" - "ed, pressing and holding down a key emits the same character over and o" - "ver againTrueTrue0Truegtk-closeFalseTrueTrueTrueTrueFalseFalse0FalseTrueend0Tr" + "ueFalse66<" + "child>TrueTrueT" + "rueFalse126TrueFalse0no" + "neTrueFa" + "lse66186Restore num l_ock state on startupFalseTrueTrueFalseTrueTrue" + "TrueFalseGeneralTrueFalse" + "True0TrueFalse0noneTrueFalse12TrueFa" + "lse66_E" + "nable key repeatFal" + "seTrueTrueFalseWhen selec" + "ted, pressing and holding down a key emits the same character over and " + "over againTrueTrueTrueFalseFalse0FalseTrue1Tr" - "ueFalse0noneTrueFalseTrueTrueFalse0noneTrueFalse612TrueFalse" + "TrueFalseChange layout option" + "FalseTrue0<" + "/packing>TrueFalse0" + "noneTrueFalse612TrueFalse12TrueFalse66TrueTrueautomaticautomaticetc" - "hed-inTrueTrue0True" - "True0TrueFalse12startgtk-add<" - "/property>FalseTrueTrue" - "TrueTrueFalseFalse0g" - "tk-editFalseTrueTrueTrue<" - "property name=\"use_stock\">TrueFalseFalse1gtk-deleteF" - "alseTrueTrueTrue<" - "/property>TrueFalseFals" - "e2<" - "/object>FalseTrue1<" - "object class=\"GtkLabel\" id=\"label8\">True" - "FalseKeyboard layout" - "TrueTrue22TrueFalse" - "_LayoutTrue2FalseTrueTrue" - "1TrueT" - "rue1button2" - "button1" - "10020001000110101000500110125020110" + "operty>TrueFalseManage layoutFalseTrue1<" + "/child>FalseTrue2TrueFalse0noneTrue" + "False12TrueFalse<" + "/property>66TrueTrueau" + "tomaticautomaticetched-in" + "TrueTrue0TrueTrue0" + "TrueFalse12sta" + "rtgtk-addFalseTrueTrueTrueTrueFalseFalse0gtk-editFalseT" + "rueTrueTrueTrue" + "False" + "False1gtk-deleteFalseTrueTrueTrueTrueFalse" + "False2FalseTrue1<" + "/object>TrueFalseK" + "eyboard layoutTrueTrue3<" + "property name=\"position\">2TrueFalse_LayoutTrue2FalseTrue<" + "property name=\"fill\">True1Tr" + "ueTrue1button1button210020001000110101000500110" + "125020110" }; -static const unsigned keyboard_dialog_ui_length = 28087u; +static const unsigned keyboard_dialog_ui_length = 30553u; diff -rupN a/dialogs/keyboard-settings/xfce-keyboard-settings.c b/dialogs/keyboard-settings/xfce-keyboard-settings.c --- a/dialogs/keyboard-settings/xfce-keyboard-settings.c 2012-04-28 20:48:30.000000000 +0000 +++ b/dialogs/keyboard-settings/xfce-keyboard-settings.c 2012-06-24 13:09:49.000000000 +0000 @@ -1,6 +1,7 @@ /* vi:set sw=2 sts=2 ts=2 et ai: */ /*- - * Copyright (c) 2008 Jannis Pohlmann + * Copyright (c) 2012 Alexsandr Sovenko + * 2008 Jannis Pohlmann * 2008 Olivier Fourdan * Portions based on xfkc * Copyright (c) 2007 Gauvain Pocentek @@ -133,9 +134,19 @@ static void xfce_ke static void xfce_keyboard_settings_add_model_to_combo (XklConfigRegistry *config_registry, const XklConfigItem *config_item, gpointer user_data); +static void xfce_keyboard_settings_add_layout_option_to_combo (XklConfigRegistry *config_registry, + const XklConfigItem *config_item, + gpointer user_data); +static void xfce_keyboard_settings_add_manage_layout_to_combo (gpointer user_data); static void xfce_keyboard_settings_init_model (XfceKeyboardSettings *settings); +static void xfce_keyboard_settings_init_layout_option (XfceKeyboardSettings *settings); +static void xfce_keyboard_settings_init_manage_layout (XfceKeyboardSettings *settings); static void xfce_keyboard_settings_model_changed_cb (GtkComboBox *combo, XfceKeyboardSettings *settings); +static void xfce_keyboard_settings_layout_option_changed_cb (GtkComboBox *combo, + XfceKeyboardSettings *settings); +static void xfce_keyboard_settings_manage_layout_changed_cb (GtkComboBox *combo, + XfceKeyboardSettings *settings); static void xfce_keyboard_settings_active_layout_cb (GtkTreeView *view, XfceKeyboardSettings *settings); static void xfce_keyboard_settings_update_layout_buttons (XfceKeyboardSettings *settings); @@ -254,6 +265,8 @@ xfce_keyboard_settings_constructed (GObj GObject *xkb_use_system_default_checkbutton; GObject *xkb_tab_layout_vbox; GObject *xkb_model_combo; + GObject *xkb_layout_option_combo; + GObject *xkb_manage_layout_combo; GObject *xkb_layout_view; GObject *xkb_layout_add_button; GObject *xkb_layout_edit_button; @@ -371,6 +384,48 @@ xfce_keyboard_settings_constructed (GObj G_CALLBACK (xfce_keyboard_settings_model_changed_cb), settings); + /* Layout option combo */ + list_store = gtk_list_store_new (XKB_COMBO_NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list_store), 0, GTK_SORT_ASCENDING); + xkl_config_registry_foreach_option (settings->priv->xkl_registry, "grp", + xfce_keyboard_settings_add_layout_option_to_combo, + list_store); + + xkb_layout_option_combo = gtk_builder_get_object (GTK_BUILDER (settings), "xkb_layout_option_combo"); + gtk_combo_box_set_model (GTK_COMBO_BOX (xkb_layout_option_combo), GTK_TREE_MODEL (list_store)); + g_object_unref (G_OBJECT (list_store)); + + gtk_cell_layout_clear (GTK_CELL_LAYOUT (xkb_layout_option_combo)); + renderer = gtk_cell_renderer_text_new (); + g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (xkb_layout_option_combo), renderer, TRUE); + gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (xkb_layout_option_combo), renderer, "text", 0); + + xfce_keyboard_settings_init_layout_option (settings); + g_signal_connect (G_OBJECT (xkb_layout_option_combo), "changed", + G_CALLBACK (xfce_keyboard_settings_layout_option_changed_cb), + settings); + + /* Manage layout combo */ + list_store = gtk_list_store_new (XKB_COMBO_NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list_store), 0, GTK_SORT_ASCENDING); + xfce_keyboard_settings_add_manage_layout_to_combo(list_store); + + xkb_manage_layout_combo = gtk_builder_get_object (GTK_BUILDER (settings), "xkb_manage_layout_combo"); + gtk_combo_box_set_model (GTK_COMBO_BOX (xkb_manage_layout_combo), GTK_TREE_MODEL (list_store)); + g_object_unref (G_OBJECT (list_store)); + + gtk_cell_layout_clear (GTK_CELL_LAYOUT (xkb_manage_layout_combo)); + renderer = gtk_cell_renderer_text_new (); + g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (xkb_manage_layout_combo), renderer, TRUE); + gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (xkb_manage_layout_combo), renderer, "text", 0); + + xfce_keyboard_settings_init_manage_layout (settings); + g_signal_connect (G_OBJECT (xkb_manage_layout_combo), "changed", + G_CALLBACK (xfce_keyboard_settings_manage_layout_changed_cb), + settings); + /* Keyboard layout/variant treeview */ settings->priv->layout_selection_treestore = NULL; xkb_layout_view = gtk_builder_get_object (GTK_BUILDER (settings), "xkb_layout_view"); @@ -1011,6 +1066,8 @@ xfce_keyboard_settings_update_sensitive { GObject *xkb_model_frame; GObject *xkb_layout_frame; + GObject *xkb_layout_option_frame; + GObject *xkb_manage_layout_frame; gboolean active; g_return_val_if_fail (XFCE_IS_KEYBOARD_SETTINGS (settings), FALSE); @@ -1018,9 +1075,13 @@ xfce_keyboard_settings_update_sensitive active = gtk_toggle_button_get_active (toggle); xkb_model_frame = gtk_builder_get_object (GTK_BUILDER (settings), "xkb_model_frame"); xkb_layout_frame = gtk_builder_get_object (GTK_BUILDER (settings), "xkb_layout_frame"); + xkb_layout_option_frame = gtk_builder_get_object (GTK_BUILDER (settings), "xkb_layout_option_frame"); + xkb_manage_layout_frame = gtk_builder_get_object (GTK_BUILDER (settings), "xkb_manage_layout_frame"); gtk_widget_set_sensitive (GTK_WIDGET (xkb_model_frame), !active); gtk_widget_set_sensitive (GTK_WIDGET (xkb_layout_frame), !active); + gtk_widget_set_sensitive (GTK_WIDGET (xkb_layout_option_frame), !active); + gtk_widget_set_sensitive (GTK_WIDGET (xkb_manage_layout_frame), !active); return active; } @@ -1062,6 +1123,8 @@ xfce_keyboard_settings_set_layout (XfceK gchar *val_variant; gchar *variants; gchar *layouts; + gchar *option; + gchar *manage; gchar *tmp; view = gtk_builder_get_object (GTK_BUILDER (settings), "xkb_layout_view"); @@ -1152,13 +1215,23 @@ xfce_keyboard_settings_set_layout (XfceK g_free (active_variant); } + option = xfconf_channel_get_string (settings->priv->keyboard_layout_channel, + "/Default/XkbLayoutOption", "grp:alt_shift_toggle"); + manage = xfconf_channel_get_string (settings->priv->keyboard_layout_channel, + "/Default/XkbManageLayout", "globally"); + xfconf_channel_set_string (settings->priv->keyboard_layout_channel, "/Default/XkbLayout", layouts); xfconf_channel_set_string (settings->priv->keyboard_layout_channel, "/Default/XkbVariant", variants); - + xfconf_channel_set_string (settings->priv->keyboard_layout_channel, + "/Default/XkbLayoutOption", option); + xfconf_channel_set_string (settings->priv->keyboard_layout_channel, + "/Default/XkbManageLayout", manage); g_free (layouts); g_free (variants); + g_free (option); + g_free (manage); } @@ -1246,7 +1319,6 @@ xfce_keyboard_settings_init_layout (Xfce } - static void xfce_keyboard_settings_add_model_to_combo (XklConfigRegistry *config_registry, const XklConfigItem *config_item, @@ -1265,6 +1337,45 @@ xfce_keyboard_settings_add_model_to_comb g_free (model_name); } +static void +xfce_keyboard_settings_add_layout_option_to_combo (XklConfigRegistry *config_registry, + const XklConfigItem *config_item, + gpointer user_data) +{ + GtkListStore *store = GTK_LIST_STORE (user_data); + GtkTreeIter iter; + gchar *model_name; + + model_name = xfce_keyboard_settings_xkb_description ((XklConfigItem *) config_item); + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + XKB_COMBO_DESCRIPTION, model_name, + XKB_COMBO_MODELS, config_item->name, -1); + g_free (model_name); +} + +static void +xfce_keyboard_settings_add_manage_layout_to_combo (gpointer user_data) +{ + GtkListStore *store = GTK_LIST_STORE (user_data); + GtkTreeIter iter; + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + XKB_COMBO_DESCRIPTION, _("Globally"), + XKB_COMBO_MODELS, "globally", -1); + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + XKB_COMBO_DESCRIPTION, _("Per window"), + XKB_COMBO_MODELS, "window", -1); + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + XKB_COMBO_DESCRIPTION, _("Per application"), + XKB_COMBO_MODELS, "application", -1); +} static void @@ -1300,7 +1411,71 @@ xfce_keyboard_settings_init_model (XfceK g_free (xkbmodel); } +static void +xfce_keyboard_settings_init_layout_option (XfceKeyboardSettings *settings) +{ + GObject *view; + GtkTreeModel *model; + GtkTreeIter iter; + gchar *id; + gchar *xkbmodel; + gboolean item; + gboolean found = FALSE; + + view = gtk_builder_get_object (GTK_BUILDER (settings), "xkb_layout_option_combo"); + model = gtk_combo_box_get_model (GTK_COMBO_BOX (view)); + + xkbmodel = xfconf_channel_get_string (settings->priv->keyboard_layout_channel, "/Default/XkbLayoutOption", "grp:alt_shift_toggle"); + item = gtk_tree_model_get_iter_first (model, &iter); + + while (item && !found) + { + gtk_tree_model_get (model, &iter, XKB_COMBO_MODELS, &id, -1); + found = !strcmp (id, xkbmodel); + g_free (id); + + if (found) + { + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (view), &iter); + break; + } + item = gtk_tree_model_iter_next (model, &iter); + } + g_free (xkbmodel); +} + +static void +xfce_keyboard_settings_init_manage_layout (XfceKeyboardSettings *settings) +{ + GObject *view; + GtkTreeModel *model; + GtkTreeIter iter; + gchar *id; + gchar *xkbmodel; + gboolean item; + gboolean found = FALSE; + + view = gtk_builder_get_object (GTK_BUILDER (settings), "xkb_manage_layout_combo"); + model = gtk_combo_box_get_model (GTK_COMBO_BOX (view)); + xkbmodel = xfconf_channel_get_string (settings->priv->keyboard_layout_channel, "/Default/XkbManageLayout", "globally"); + item = gtk_tree_model_get_iter_first (model, &iter); + + while (item && !found) + { + gtk_tree_model_get (model, &iter, XKB_COMBO_MODELS, &id, -1); + found = !strcmp (id, xkbmodel); + g_free (id); + + if (found) + { + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (view), &iter); + break; + } + item = gtk_tree_model_iter_next (model, &iter); + } + g_free (xkbmodel); +} static void xfce_keyboard_settings_active_layout_cb (GtkTreeView *view, @@ -1336,7 +1511,35 @@ xfce_keyboard_settings_model_changed_cb g_free (xkbmodel); } +static void +xfce_keyboard_settings_layout_option_changed_cb (GtkComboBox *combo, + XfceKeyboardSettings *settings) +{ + GtkTreeModel *model; + GtkTreeIter iter; + gchar *xkbmodel; + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter); + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); + gtk_tree_model_get (model, &iter, XKB_COMBO_MODELS, &xkbmodel, -1); + xfconf_channel_set_string (settings->priv->keyboard_layout_channel, "/Default/XkbLayoutOption", xkbmodel); + g_free (xkbmodel); +} + +static void +xfce_keyboard_settings_manage_layout_changed_cb (GtkComboBox *combo, + XfceKeyboardSettings *settings) +{ + GtkTreeModel *model; + GtkTreeIter iter; + gchar *xkbmodel; + + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter); + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); + gtk_tree_model_get (model, &iter, XKB_COMBO_MODELS, &xkbmodel, -1); + xfconf_channel_set_string (settings->priv->keyboard_layout_channel, "/Default/XkbManageLayout", xkbmodel); + g_free (xkbmodel); +} static void xfce_keyboard_settings_update_layout_buttons (XfceKeyboardSettings *settings) diff -rupN a/xfsettingsd/keyboard-layout.c b/xfsettingsd/keyboard-layout.c --- a/xfsettingsd/keyboard-layout.c 2012-04-28 20:48:30.000000000 +0000 +++ b/xfsettingsd/keyboard-layout.c 2012-06-24 22:34:53.000000000 +0000 @@ -1,5 +1,6 @@ /* - * Copyright (c) 2008 Olivier Fourdan + * Copyright (c) 2012 Alexsandr Sovenko + * 2008 Olivier Fourdan * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,8 +45,18 @@ #include "debug.h" #include "keyboard-layout.h" +#ifdef HAVE_LIBWNCK +#include +#include +#include +#include +#endif /*HAVE_LIBWNCK*/ + +static void xfce_keyboard_layout_helper_finalize (GObject *object); static void xfce_keyboard_layout_helper_process_xmodmap (void); static void xfce_keyboard_layout_helper_set_model (XfceKeyboardLayoutHelper *helper); +static void xfce_keyboard_layout_helper_set_layout_option (XfceKeyboardLayoutHelper *helper); +static void xfce_keyboard_layout_helper_set_manage_layout (XfceKeyboardLayoutHelper *helper); static void xfce_keyboard_layout_helper_set_layout (XfceKeyboardLayoutHelper *helper); static void xfce_keyboard_layout_helper_set_variant (XfceKeyboardLayoutHelper *helper); static void xfce_keyboard_layout_helper_channel_property_changed (XfconfChannel *channel, @@ -73,14 +84,234 @@ struct _XfceKeyboardLayoutHelper XklConfigRegistry *registry; XklConfigRec *config; #endif /* HAVE_LIBXKLAVIER */ + +#ifdef HAVE_LIBWNCK + GHashTable *application_map; + GHashTable *window_map; + gint current_application_id; + gint current_window_id; + + /* Dbus */ + DBusConnection *bus; + DBusError error; + gchar *lang; + gchar *xkbmanlay; + /* Dbus */ +#endif /*HAVE_LIBWNCK*/ }; G_DEFINE_TYPE (XfceKeyboardLayoutHelper, xfce_keyboard_layout_helper, G_TYPE_OBJECT); +#ifdef HAVE_LIBWNCK + +DBusHandlerResult +xfce_keyboard_manage_layout_signal_filter (DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + XfceKeyboardLayoutHelper *helper = (XfceKeyboardLayoutHelper *) user_data; + + DBusError error; + gint group; + + if (dbus_message_is_signal + (message, DBUS_INTERFACE_LOCAL, "Disconnected")) + return DBUS_HANDLER_RESULT_HANDLED; + else if (dbus_message_is_signal (message, "org.xfce.SettingsDaemon.KeyboardLayoutHelper.Signal", "layoutset")) + { + dbus_error_init (&error); + if (dbus_message_get_args (message, &error, + DBUS_TYPE_INT32, &group, + DBUS_TYPE_INVALID)) + { + if(!strcmp(helper->xkbmanlay,"window")) + g_hash_table_insert (helper->window_map, + GINT_TO_POINTER (helper->current_window_id), + GINT_TO_POINTER (group)); + if(!strcmp(helper->xkbmanlay,"application")) + g_hash_table_insert (helper->application_map, + GINT_TO_POINTER (helper->current_application_id), + GINT_TO_POINTER (group)); + + xkl_engine_lock_group (helper->engine, group); + } else + { + g_print("`layoutset` received, but error getting message: %s\n", + error.message); + dbus_error_free (&error); + } + return DBUS_HANDLER_RESULT_HANDLED; + } + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +GdkFilterReturn +xfce_keyboard_manage_layout_handle_xevent (GdkXEvent *xev, + GdkEvent *event, +XfceKeyboardLayoutHelper *helper) +{ + XEvent *xevent = (XEvent *) xev; + xkl_engine_filter_events (helper->engine, xevent); + return GDK_FILTER_CONTINUE; +} + static void -xfce_keyboard_layout_helper_class_init (XfceKeyboardLayoutHelperClass *klass) +xfce_keyboard_manage_layout_init (XfceKeyboardLayoutHelper *helper) { + void + active_window_changed_cb (WnckScreen *screen, + WnckWindow *previously_active_window, + XfceKeyboardLayoutHelper *helper) + { + if (helper->xkb_disable_settings) return; + if (!strcmp (helper->xkbmanlay, "globally")) return; + + WnckWindow *window = wnck_screen_get_active_window (screen); + if (!WNCK_IS_WINDOW (window)) return; + guint window_id = wnck_window_get_xid (window); + guint application_id = wnck_window_get_pid (window); + helper->current_application_id = application_id; + helper->current_window_id = window_id; + + gint group = 0; + gpointer key, value; + + if (!strcmp (helper->xkbmanlay, "window")) + { + if (g_hash_table_lookup_extended (helper->window_map, + GINT_TO_POINTER (window_id), &key, &value)) + group = GPOINTER_TO_INT (value); + + g_hash_table_insert (helper->window_map, + GINT_TO_POINTER (window_id), + GINT_TO_POINTER (group)); + + xkl_engine_lock_group (helper->engine, group); + } + + if (!strcmp (helper->xkbmanlay, "application")) + { + if (g_hash_table_lookup_extended (helper->application_map, + GINT_TO_POINTER (application_id), &key, &value)) + group = GPOINTER_TO_INT (value); + g_hash_table_insert (helper->application_map, + GINT_TO_POINTER (application_id), + GINT_TO_POINTER (group)); + + xkl_engine_lock_group (helper->engine, group); + } + } + + void + application_closed_cb (WnckScreen *screen, + WnckApplication *app, + XfceKeyboardLayoutHelper *helper) + { + if (helper->xkb_disable_settings) return; + guint application_id = wnck_application_get_pid (app); + + if (!strcmp (helper->xkbmanlay, "window")) return; + + if (!strcmp (helper->xkbmanlay, "application")) + g_hash_table_remove (helper->application_map, + GINT_TO_POINTER (application_id)); + } + + void + window_closed_cb (WnckScreen *screen, + WnckWindow *window, + XfceKeyboardLayoutHelper *helper) + { + if (helper->xkb_disable_settings) return; + guint window_id = wnck_window_get_xid (window); + + if (!strcmp (helper->xkbmanlay, "application")) return; + + if (!strcmp (helper->xkbmanlay,"window")) + g_hash_table_remove (helper->window_map, + GINT_TO_POINTER (window_id)); + } + + void + X_state_changed_cb (XklEngine *engine, + XklEngineStateChange *change, + gint group, + gboolean restore, + XfceKeyboardLayoutHelper *helper) + { + if (change == GROUP_CHANGED) + { + if (!strcmp (helper->xkbmanlay, "window")) + g_hash_table_insert (helper->window_map, + GINT_TO_POINTER (helper->current_window_id), + GINT_TO_POINTER (group)); + + if (!strcmp (helper->xkbmanlay, "application")) + g_hash_table_insert (helper->application_map, + GINT_TO_POINTER (helper->current_application_id), + GINT_TO_POINTER (group)); + + if (helper->bus) + { + DBusMessage *message = + dbus_message_new_signal ("/org/xfce/SettingsDaemon/KeyboardLayoutHelper/layoutget", + "org.xfce.SettingsDaemon.KeyboardLayoutHelper.Signal", + "layoutget"); + dbus_message_append_args (message, + DBUS_TYPE_INT32, &group, + DBUS_TYPE_INVALID); + dbus_connection_send (helper->bus, message, NULL); + dbus_message_unref (message); + } + + } + } + + dbus_error_init (&helper->error); + helper->bus = dbus_bus_get (DBUS_BUS_SESSION, &helper->error); + if (!helper->bus) + { + g_warning ("Failed to connect to the D-BUS daemon: %s", helper->error.message); + dbus_error_free (&helper->error); + } else + { + dbus_connection_setup_with_g_main (helper->bus, NULL); + dbus_bus_add_match (helper->bus, "type='signal',interface='org.xfce.SettingsDaemon.KeyboardLayoutHelper.Signal'", NULL); + dbus_connection_add_filter (helper->bus, + xfce_keyboard_manage_layout_signal_filter, helper, NULL); + } + helper->window_map = g_hash_table_new (g_direct_hash, NULL); + helper->application_map = g_hash_table_new (g_direct_hash, NULL); + + xkl_engine_set_group_per_toplevel_window (helper->engine, FALSE); + xkl_engine_start_listen (helper->engine, XKLL_TRACK_KEYBOARD_STATE); + + g_signal_connect (helper->engine, "X-state-changed", + G_CALLBACK (X_state_changed_cb), helper); + + gdk_window_add_filter (NULL, + (GdkFilterFunc) xfce_keyboard_manage_layout_handle_xevent, helper); + + WnckScreen *wnck_screen = wnck_screen_get_default (); + + g_signal_connect (G_OBJECT (wnck_screen), "active-window-changed", + G_CALLBACK (active_window_changed_cb), helper); + + g_signal_connect (G_OBJECT (wnck_screen), "window-closed", + G_CALLBACK (window_closed_cb), helper); + + g_signal_connect (G_OBJECT (wnck_screen), "application-closed", + G_CALLBACK (application_closed_cb), helper); +} +#endif /*HAVE_LIBWNCK*/ + +static void +xfce_keyboard_layout_helper_class_init (XfceKeyboardLayoutHelperClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->finalize = xfce_keyboard_layout_helper_finalize; + g_type_class_add_private (klass, sizeof (XfceKeyboardLayoutHelper)); } static void @@ -104,13 +335,35 @@ xfce_keyboard_layout_helper_init (XfceKe /* load settings */ helper->xkb_disable_settings = xfconf_channel_get_bool (helper->channel, "/Default/XkbDisable", TRUE); xfce_keyboard_layout_helper_set_model (helper); + xfce_keyboard_layout_helper_set_layout_option (helper); + xfce_keyboard_layout_helper_set_manage_layout (helper); xfce_keyboard_layout_helper_set_layout (helper); xfce_keyboard_layout_helper_set_variant (helper); xfce_keyboard_layout_helper_process_xmodmap (); + +#ifdef HAVE_LIBWNCK + /* init manage layout */ + xfce_keyboard_manage_layout_init (helper); +#endif /*HAVE_LIBWNCK*/ } +static void +xfce_keyboard_layout_helper_finalize (GObject *object) +{ + XfceKeyboardLayoutHelper *helper = XFCE_KEYBOARD_LAYOUT_HELPER (object); + + gdk_window_remove_filter (NULL, + (GdkFilterFunc) xfce_keyboard_manage_layout_handle_xevent, NULL); + xkl_engine_stop_listen (helper->engine, XKLL_TRACK_KEYBOARD_STATE); + +#ifdef HAVE_DBUS + dbus_connection_remove_filter (helper->bus, + xfce_keyboard_manage_layout_signal_filter, helper); +#endif /* HAVE_DBUS */ + (*G_OBJECT_CLASS (xfce_keyboard_layout_helper_parent_class)->finalize) (object); +} static void xfce_keyboard_layout_helper_process_xmodmap (void) @@ -157,6 +410,41 @@ xfce_keyboard_layout_helper_set_model (X } static void +xfce_keyboard_layout_helper_set_layout_option (XfceKeyboardLayoutHelper *helper) +{ +#ifdef HAVE_LIBXKLAVIER + gchar *default_layout_option, *val_layout; + + if (!helper->xkb_disable_settings) + { + default_layout_option = g_strjoinv(",", helper->config->layouts); + val_layout = xfconf_channel_get_string (helper->channel, "/Default/XkbLayoutOption", default_layout_option); + //layouts = ; + g_strfreev(helper->config->options); + helper->config->options = g_strsplit_set (val_layout, ",", 0); + xkl_config_rec_activate (helper->config, helper->engine); + g_free (default_layout_option); + + xfsettings_dbg (XFSD_DEBUG_KEYBOARD_LAYOUT, "set layout option to \"%s\"", val_layout); + g_free (val_layout); + } + +#endif /* HAVE_LIBXKLAVIER */ +} + +static void +xfce_keyboard_layout_helper_set_manage_layout (XfceKeyboardLayoutHelper *helper) +{ +#ifdef HAVE_LIBXKLAVIER + if (!helper->xkb_disable_settings) + { + helper->xkbmanlay = xfconf_channel_get_string (helper->channel, "/Default/XkbManageLayout", "globally"); + xfsettings_dbg (XFSD_DEBUG_KEYBOARD_LAYOUT, "set manage layout to \"%s\"", helper->xkbmanlay); + } +#endif /* HAVE_LIBXKLAVIER */ +} + +static void xfce_keyboard_layout_helper_set_layout (XfceKeyboardLayoutHelper *helper) { #ifdef HAVE_LIBXKLAVIER @@ -215,6 +503,8 @@ xfce_keyboard_layout_helper_channel_prop helper->xkb_disable_settings = g_value_get_boolean (value); /* Apply all settings */ xfce_keyboard_layout_helper_set_model (helper); + xfce_keyboard_layout_helper_set_layout_option (helper); + xfce_keyboard_layout_helper_set_manage_layout (helper); xfce_keyboard_layout_helper_set_layout (helper); xfce_keyboard_layout_helper_set_variant (helper); } @@ -222,6 +512,14 @@ xfce_keyboard_layout_helper_channel_prop { xfce_keyboard_layout_helper_set_layout (helper); } + else if (strcmp (property_name, "/Default/XkbLayoutOption") == 0) + { + xfce_keyboard_layout_helper_set_layout_option (helper); + } + else if (strcmp (property_name, "/Default/XkbManageLayout") == 0) + { + xfce_keyboard_layout_helper_set_manage_layout (helper); + } else if (strcmp (property_name, "/Default/XkbLayout") == 0) { xfce_keyboard_layout_helper_set_layout (helper);