eekboard: simplify layouts/variants menu creation.
This commit is contained in:
185
src/eekboard.c
185
src/eekboard.c
@ -48,15 +48,48 @@ Window target;
|
|||||||
EekLayout *layout;
|
EekLayout *layout;
|
||||||
EekKeyboard *eek_keyboard;
|
EekKeyboard *eek_keyboard;
|
||||||
|
|
||||||
static void on_monitor_key_event_toggled (GtkToggleAction *action,
|
|
||||||
GtkWidget *window);
|
|
||||||
|
|
||||||
static const GOptionEntry options[] = {
|
static const GOptionEntry options[] = {
|
||||||
{"window-id", '\0', 0, G_OPTION_ARG_STRING, &window_id,
|
{"window-id", '\0', 0, G_OPTION_ARG_STRING, &window_id,
|
||||||
"the target window ID; use xwininfo to obtain the value", NULL},
|
"the target window ID; use xwininfo to obtain the value", NULL},
|
||||||
{NULL},
|
{NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void on_monitor_key_event_toggled (GtkToggleAction *action,
|
||||||
|
GtkWidget *window);
|
||||||
|
|
||||||
|
static const char ui_description[] =
|
||||||
|
"<ui>"
|
||||||
|
" <menubar name='MainMenu'>"
|
||||||
|
" <menu action='FileMenu'>"
|
||||||
|
" <menuitem action='Quit'/>"
|
||||||
|
" </menu>"
|
||||||
|
" <menu action='KeyboardMenu'>"
|
||||||
|
" <menuitem action='MonitorKeyEvent'/>"
|
||||||
|
" <menu action='SetLayout'>"
|
||||||
|
" <placeholder name='LayoutsPH'/>"
|
||||||
|
" </menu>"
|
||||||
|
" </menu>"
|
||||||
|
" <menu action='HelpMenu'>"
|
||||||
|
" <menuitem action='About'/>"
|
||||||
|
" </menu>"
|
||||||
|
" </menubar>"
|
||||||
|
"</ui>";
|
||||||
|
|
||||||
|
#define SET_LAYOUT_UI_PATH "/MainMenu/KeyboardMenu/SetLayout/LayoutsPH"
|
||||||
|
|
||||||
|
struct _LayoutVariant {
|
||||||
|
gchar *layout;
|
||||||
|
gchar *variant;
|
||||||
|
};
|
||||||
|
typedef struct _LayoutVariant LayoutVariant;
|
||||||
|
|
||||||
|
struct _LayoutCallbackData {
|
||||||
|
GtkUIManager *ui_manager;
|
||||||
|
GtkActionGroup *action_group;
|
||||||
|
guint merge_id;
|
||||||
|
};
|
||||||
|
typedef struct _LayoutCallbackData LayoutCallbackData;
|
||||||
|
|
||||||
static const GtkActionEntry action_entry[] = {
|
static const GtkActionEntry action_entry[] = {
|
||||||
{"FileMenu", NULL, N_("_File")},
|
{"FileMenu", NULL, N_("_File")},
|
||||||
{"KeyboardMenu", NULL, N_("_Keyboard")},
|
{"KeyboardMenu", NULL, N_("_Keyboard")},
|
||||||
@ -82,12 +115,6 @@ on_monitor_key_event_toggled (GtkToggleAction *action,
|
|||||||
g_object_set (G_OBJECT(window), "can_focus", active, NULL);
|
g_object_set (G_OBJECT(window), "can_focus", active, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _EekBoardLayoutVariant {
|
|
||||||
gchar *layout;
|
|
||||||
gchar *variant;
|
|
||||||
};
|
|
||||||
typedef struct _EekBoardLayoutVariant EekBoardLayoutVariant;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_key_pressed (EekKeyboard *keyboard,
|
on_key_pressed (EekKeyboard *keyboard,
|
||||||
EekKey *key)
|
EekKey *key)
|
||||||
@ -105,7 +132,7 @@ on_key_released (EekKeyboard *keyboard,
|
|||||||
static void
|
static void
|
||||||
on_activate (GtkAction *action, gpointer user_data)
|
on_activate (GtkAction *action, gpointer user_data)
|
||||||
{
|
{
|
||||||
EekBoardLayoutVariant *config = user_data;
|
LayoutVariant *config = user_data;
|
||||||
gchar *layouts[2], *variants[2], **vp = NULL;
|
gchar *layouts[2], *variants[2], **vp = NULL;
|
||||||
|
|
||||||
layouts[0] = config->layout;
|
layouts[0] = config->layout;
|
||||||
@ -149,7 +176,8 @@ on_changed (EekLayout *layout, gpointer user_data)
|
|||||||
gfloat width, height;
|
gfloat width, height;
|
||||||
|
|
||||||
clutter_actor_get_size (stage, &width, &height);
|
clutter_actor_get_size (stage, &width, &height);
|
||||||
actor = clutter_container_find_child_by_name (stage, "keyboard");
|
actor = clutter_container_find_child_by_name (CLUTTER_CONTAINER(stage),
|
||||||
|
"keyboard");
|
||||||
|
|
||||||
/* FIXME: currently keyboard must be finalized before actor. */
|
/* FIXME: currently keyboard must be finalized before actor. */
|
||||||
g_object_unref (eek_keyboard);
|
g_object_unref (eek_keyboard);
|
||||||
@ -158,68 +186,33 @@ on_changed (EekLayout *layout, gpointer user_data)
|
|||||||
eek_keyboard = create_keyboard (stage, layout, width, height);
|
eek_keyboard = create_keyboard (stage, layout, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char ui_description[] =
|
|
||||||
"<ui>"
|
|
||||||
" <menubar name='MainMenu'>"
|
|
||||||
" <menu action='FileMenu'>"
|
|
||||||
" <menuitem action='Quit'/>"
|
|
||||||
" </menu>"
|
|
||||||
" <menu action='KeyboardMenu'>"
|
|
||||||
" <menuitem action='MonitorKeyEvent'/>"
|
|
||||||
" <menu action='SetLayout'>"
|
|
||||||
" <placeholder name='LayoutsPH'/>"
|
|
||||||
" </menu>"
|
|
||||||
" </menu>"
|
|
||||||
" <menu action='HelpMenu'>"
|
|
||||||
" <menuitem action='About'/>"
|
|
||||||
" </menu>"
|
|
||||||
" </menubar>"
|
|
||||||
"</ui>";
|
|
||||||
|
|
||||||
#define SET_LAYOUT_UI_PATH "/MainMenu/KeyboardMenu/SetLayout/LayoutsPH"
|
|
||||||
|
|
||||||
struct _EekBoardAddLayoutData {
|
|
||||||
GtkUIManager *ui_manager;
|
|
||||||
GtkActionGroup *action_group;
|
|
||||||
guint merge_id;
|
|
||||||
};
|
|
||||||
typedef struct _EekBoardAddLayoutData EekBoardAddLayoutData;
|
|
||||||
|
|
||||||
struct _EekBoardAddVariantData {
|
|
||||||
gchar *name;
|
|
||||||
gchar *description;
|
|
||||||
};
|
|
||||||
typedef struct _EekBoardAddVariantData EekBoardAddVariantData;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
variant_callback (XklConfigRegistry *registry,
|
variant_callback (XklConfigRegistry *registry,
|
||||||
XklConfigItem *item,
|
const XklConfigItem *item,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
EekBoardAddVariantData *variant_data;
|
GSList **r_variants = user_data;
|
||||||
GSList **head = user_data;
|
XklConfigItem *_item;
|
||||||
|
|
||||||
variant_data = g_slice_new (EekBoardAddVariantData);
|
_item = g_slice_dup (XklConfigItem, item);
|
||||||
variant_data->name = g_strdup (item->name);
|
*r_variants = g_slist_prepend (*r_variants, _item);
|
||||||
variant_data->description = g_strdup (item->description);
|
|
||||||
*head = g_slist_prepend (*head, variant_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
layout_callback (XklConfigRegistry *registry,
|
layout_callback (XklConfigRegistry *registry,
|
||||||
XklConfigItem *item,
|
const XklConfigItem *item,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
LayoutCallbackData *data = user_data;
|
||||||
GtkAction *action;
|
GtkAction *action;
|
||||||
EekBoardAddLayoutData *layout_data = user_data;
|
|
||||||
GSList *variants = NULL;
|
GSList *variants = NULL;
|
||||||
char layout_action_name[128], variant_action_name[128];
|
char layout_action_name[128], variant_action_name[128];
|
||||||
EekBoardLayoutVariant *data;
|
LayoutVariant *config;
|
||||||
|
|
||||||
g_snprintf (layout_action_name, sizeof (layout_action_name),
|
g_snprintf (layout_action_name, sizeof (layout_action_name),
|
||||||
"SetLayout%s", item->name);
|
"SetLayout%s", item->name);
|
||||||
action = gtk_action_new (layout_action_name, item->description, NULL, NULL);
|
action = gtk_action_new (layout_action_name, item->description, NULL, NULL);
|
||||||
gtk_action_group_add_action (layout_data->action_group, action);
|
gtk_action_group_add_action (data->action_group, action);
|
||||||
|
|
||||||
xkl_config_registry_foreach_layout_variant (registry,
|
xkl_config_registry_foreach_layout_variant (registry,
|
||||||
item->name,
|
item->name,
|
||||||
@ -227,14 +220,13 @@ layout_callback (XklConfigRegistry *registry,
|
|||||||
&variants);
|
&variants);
|
||||||
|
|
||||||
if (!variants) {
|
if (!variants) {
|
||||||
data = g_slice_new (EekBoardLayoutVariant);
|
config = g_slice_new (LayoutVariant);
|
||||||
data->layout = g_strdup (item->name);
|
config->layout = g_strdup (item->name);
|
||||||
data->variant = NULL;
|
config->variant = NULL;
|
||||||
g_signal_connect (action, "activate", G_CALLBACK (on_activate),
|
g_signal_connect (action, "activate", G_CALLBACK (on_activate), config);
|
||||||
data);
|
|
||||||
|
|
||||||
g_object_unref (action);
|
g_object_unref (action);
|
||||||
gtk_ui_manager_add_ui (layout_data->ui_manager, layout_data->merge_id,
|
gtk_ui_manager_add_ui (data->ui_manager, data->merge_id,
|
||||||
SET_LAYOUT_UI_PATH,
|
SET_LAYOUT_UI_PATH,
|
||||||
layout_action_name, layout_action_name,
|
layout_action_name, layout_action_name,
|
||||||
GTK_UI_MANAGER_MENUITEM, FALSE);
|
GTK_UI_MANAGER_MENUITEM, FALSE);
|
||||||
@ -243,8 +235,7 @@ layout_callback (XklConfigRegistry *registry,
|
|||||||
GSList *head;
|
GSList *head;
|
||||||
|
|
||||||
g_object_unref (action);
|
g_object_unref (action);
|
||||||
gtk_ui_manager_add_ui (layout_data->ui_manager,
|
gtk_ui_manager_add_ui (data->ui_manager, data->merge_id,
|
||||||
layout_data->merge_id,
|
|
||||||
SET_LAYOUT_UI_PATH,
|
SET_LAYOUT_UI_PATH,
|
||||||
layout_action_name, layout_action_name,
|
layout_action_name, layout_action_name,
|
||||||
GTK_UI_MANAGER_MENU, FALSE);
|
GTK_UI_MANAGER_MENU, FALSE);
|
||||||
@ -252,37 +243,57 @@ layout_callback (XklConfigRegistry *registry,
|
|||||||
SET_LAYOUT_UI_PATH "/%s", layout_action_name);
|
SET_LAYOUT_UI_PATH "/%s", layout_action_name);
|
||||||
|
|
||||||
for (head = variants; head; head = head->next) {
|
for (head = variants; head; head = head->next) {
|
||||||
EekBoardAddVariantData *variant_data = head->data;
|
XklConfigItem *_item = head->data;
|
||||||
|
|
||||||
g_snprintf (variant_action_name, sizeof (variant_action_name),
|
g_snprintf (variant_action_name, sizeof (variant_action_name),
|
||||||
"SetVariant%s%s", item->name, variant_data->name);
|
"SetVariant%s%s", item->name, _item->name);
|
||||||
action = gtk_action_new (variant_action_name,
|
action = gtk_action_new (variant_action_name,
|
||||||
variant_data->description,
|
_item->description,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
data = g_slice_new (EekBoardLayoutVariant);
|
config = g_slice_new (LayoutVariant);
|
||||||
data->layout = g_strdup (item->name);
|
config->layout = g_strdup (item->name);
|
||||||
data->variant = g_strdup (variant_data->name);
|
config->variant = g_strdup (_item->name);
|
||||||
g_signal_connect (action, "activate", G_CALLBACK (on_activate),
|
g_signal_connect (action, "activate", G_CALLBACK (on_activate),
|
||||||
data);
|
config);
|
||||||
|
|
||||||
gtk_action_group_add_action (layout_data->action_group, action);
|
gtk_action_group_add_action (data->action_group, action);
|
||||||
g_object_unref (action);
|
g_object_unref (action);
|
||||||
|
|
||||||
gtk_ui_manager_add_ui (layout_data->ui_manager,
|
gtk_ui_manager_add_ui (data->ui_manager, data->merge_id,
|
||||||
layout_data->merge_id,
|
|
||||||
layout_path,
|
layout_path,
|
||||||
variant_action_name, variant_action_name,
|
variant_action_name, variant_action_name,
|
||||||
GTK_UI_MANAGER_MENUITEM, FALSE);
|
GTK_UI_MANAGER_MENUITEM, FALSE);
|
||||||
g_free (variant_data->name);
|
g_slice_free (XklConfigItem, _item);
|
||||||
g_free (variant_data->description);
|
|
||||||
g_slice_free (EekBoardAddVariantData, variant_data);
|
|
||||||
}
|
}
|
||||||
g_slist_free (variants);
|
g_slist_free (variants);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_layouts_menu (GtkUIManager *ui_manager)
|
||||||
|
{
|
||||||
|
XklEngine *engine;
|
||||||
|
XklConfigRegistry *registry;
|
||||||
|
Display *display;
|
||||||
|
LayoutCallbackData data;
|
||||||
|
|
||||||
|
data.ui_manager = ui_manager;
|
||||||
|
data.action_group = gtk_action_group_new ("Layouts");
|
||||||
|
gtk_ui_manager_insert_action_group (data.ui_manager, data.action_group, -1);
|
||||||
|
data.merge_id = gtk_ui_manager_new_merge_id (ui_manager);
|
||||||
|
|
||||||
|
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||||
|
g_return_if_fail (display);
|
||||||
|
|
||||||
|
engine = xkl_engine_get_instance (display);
|
||||||
|
registry = xkl_config_registry_get_instance (engine);
|
||||||
|
xkl_config_registry_load (registry, FALSE);
|
||||||
|
|
||||||
|
xkl_config_registry_foreach_layout (registry, layout_callback, &data);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
create_menus (GtkWidget *window, GtkUIManager * ui_manager)
|
create_menus (GtkWidget *window, GtkUIManager * ui_manager)
|
||||||
{
|
{
|
||||||
@ -293,26 +304,12 @@ create_menus (GtkWidget *window, GtkUIManager * ui_manager)
|
|||||||
gtk_action_group_add_actions (action_group, action_entry,
|
gtk_action_group_add_actions (action_group, action_entry,
|
||||||
G_N_ELEMENTS (action_entry), window);
|
G_N_ELEMENTS (action_entry), window);
|
||||||
gtk_action_group_add_toggle_actions (action_group, toggle_action_entry,
|
gtk_action_group_add_toggle_actions (action_group, toggle_action_entry,
|
||||||
G_N_ELEMENTS (toggle_action_entry), window);
|
G_N_ELEMENTS (toggle_action_entry),
|
||||||
|
window);
|
||||||
|
|
||||||
gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
|
gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
|
||||||
gtk_ui_manager_add_ui_from_string (ui_manager, ui_description, -1, NULL);
|
gtk_ui_manager_add_ui_from_string (ui_manager, ui_description, -1, NULL);
|
||||||
|
create_layouts_menu (ui_manager);
|
||||||
EekBoardAddLayoutData data;
|
|
||||||
|
|
||||||
data.action_group = gtk_action_group_new ("Layouts");
|
|
||||||
gtk_ui_manager_insert_action_group (ui_manager, data.action_group, -1);
|
|
||||||
data.merge_id = gtk_ui_manager_new_merge_id (ui_manager);
|
|
||||||
|
|
||||||
XklEngine *engine;
|
|
||||||
XklConfigRegistry *registry;
|
|
||||||
|
|
||||||
engine = xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
|
|
||||||
registry = xkl_config_registry_get_instance (engine);
|
|
||||||
xkl_config_registry_load (registry, FALSE);
|
|
||||||
data.ui_manager = ui_manager;
|
|
||||||
data.action_group = action_group;
|
|
||||||
xkl_config_registry_foreach_layout (registry, layout_callback, &data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -365,7 +362,7 @@ main (int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (window_id) {
|
if (window_id) {
|
||||||
if (strncmp (window_id, "0x", 2) == 0)
|
if (strncmp (window_id, "0x", 2) == 0)
|
||||||
target = strtol (window_id[2], NULL, 16);
|
target = strtol (&window_id[2], NULL, 16);
|
||||||
else
|
else
|
||||||
target = strtol (window_id, NULL, 10);
|
target = strtol (window_id, NULL, 10);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user