Make gtk plugin to show commands list, no add/delete/edit yet.
authorAndriy Grytsenko <andrej@rep.kiev.ua>
Tue, 25 Oct 2016 10:20:15 +0000 (13:20 +0300)
committerAndriy Grytsenko <andrej@rep.kiev.ua>
Tue, 25 Oct 2016 10:20:15 +0000 (13:20 +0300)
.gitignore
plugins/Makefile.am
plugins/gtk.c
plugins/lxhotkey-gtk.desktop.in [new file with mode: 0644]
plugins/openbox.c
po/POTFILES.in
po/lxhotkey.pot
src/lxhotkey.c
src/lxhotkey.h

index 341fb40..8a826da 100644 (file)
@@ -29,3 +29,4 @@ lxhotkey
 *.pc
 *.tar.xz
 man/lxhotkey.1
+*.desktop
index 5464a21..a087a4b 100644 (file)
@@ -21,14 +21,27 @@ endif
 ob_la_SOURCES = openbox.c
 ob_la_LIBADD = -lfm-extra
 
+# GTK module
+gtk_la_SOURCES = gtk.c
+gtk_la_CFLAGS = $(GTK_CFLAGS)
+gtk_la_LIBADD = $(GTK_LIBS)
+
+
+# .desktop files
+desktopdir=$(datadir)/applications
+desktop_in_files =
+if WITH_GTK
+desktop_in_files += lxhotkey-gtk.desktop.in
+endif
+desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
+@INTLTOOL_DESKTOP_RULE@
+
+EXTRA_DIST= \
+       lxhotkey-gtk.desktop.in lxhotkey-gtk.desktop
+
 install-exec-hook:
        rm -f $(DESTDIR)$(pkglibdir)/*.la
 
 PLUGINS_INSTALLED = $(pkglib_LTLIBRARIES:.la=.so)
 uninstall-hook:
        cd $(DESTDIR)$(pkglibdir) && rm -f $(PLUGINS_INSTALLED) || true
-
-# GTK module
-gtk_la_SOURCES = gtk.c
-gtk_la_CFLAGS = $(GTK_CFLAGS)
-gtk_la_LIBADD = $(GTK_LIBS)
index 34bf4ed..67b52f2 100644 (file)
 #include <glib/gi18n-lib.h>
 #include <gtk/gtk.h>
 
+static int inited = 0;
+
 typedef struct {
     const gchar *wm;
     const LXHotkeyPluginInit *cb;
     gpointer config;
+    GtkNotebook *notebook;
+    GtkWidget *acts, *apps;
 } PluginData;
 
 static const char menu_xml[] =
 "<menubar>"
   "<menu action='FileMenu'>"
     "<menuitem action='Save'/>"
+    "<menuitem action='Reload'/>"
     "<menuitem action='Quit'/>"
   "</menu>"
   "<menu action='EditMenu'>"
@@ -49,6 +54,7 @@ static const char menu_xml[] =
   "</menu>"
 "</menubar>"
 "<toolbar>"
+    "<toolitem action='Reload'/>"
     "<toolitem action='Save'/>"
     "<separator/>"
     "<toolitem action='New'/>"
@@ -56,6 +62,10 @@ static const char menu_xml[] =
     "<toolitem action='Edit'/>"
 "</toolbar>";
 
+static void on_reload(GtkAction *act, PluginData *data)
+{
+}
+
 static void on_save(GtkAction *act, PluginData *data)
 {
 }
@@ -84,12 +94,21 @@ static void on_about(GtkAction *act, PluginData *data)
 static GtkActionEntry actions[] =
 {
     { "FileMenu", NULL, N_("_File"), NULL, NULL, NULL },
-        { "Save", GTK_STOCK_SAVE, NULL, NULL, NULL, G_CALLBACK(on_save) },
-        { "Quit", GTK_STOCK_QUIT, NULL, NULL, NULL, G_CALLBACK(on_quit) },
+        { "Reload", GTK_STOCK_UNDO, N_("_Reload"), NULL,
+                    N_("Drop all unsaved changes and reload all keys from Window Manager configuration"),
+                    G_CALLBACK(on_reload) },
+        { "Save", GTK_STOCK_SAVE, NULL, NULL,
+                    N_("Save all changes and apply them to Window Manager configuration"),
+                    G_CALLBACK(on_save) },
+        { "Quit", GTK_STOCK_QUIT, NULL, NULL,
+                    N_("Exit the application without saving"), G_CALLBACK(on_quit) },
     { "EditMenu", NULL, N_("_Edit"), NULL, NULL, NULL },
-        { "New", GTK_STOCK_NEW, NULL, NULL, NULL, G_CALLBACK(on_new) },
-        { "Del", GTK_STOCK_DELETE, NULL, "", NULL, G_CALLBACK(on_del) },
-        { "Edit", GTK_STOCK_EDIT, NULL, NULL, NULL, G_CALLBACK(on_edit) },
+        { "New", GTK_STOCK_NEW, NULL, NULL, N_("Create new action"),
+                    G_CALLBACK(on_new) },
+        { "Del", GTK_STOCK_DELETE, NULL, "", N_("Remove selected action"),
+                    G_CALLBACK(on_del) },
+        { "Edit", GTK_STOCK_EDIT, NULL, NULL, N_("Change selected action"),
+                    G_CALLBACK(on_edit) },
     { "HelpMenu", NULL, N_("_Help"), NULL, NULL, NULL },
         { "About", GTK_STOCK_ABOUT, NULL, NULL, NULL, G_CALLBACK(on_about) }
 };
@@ -99,6 +118,34 @@ static void on_notebook_switch_page(GtkNotebook *nb, gpointer *page, guint num,
 {
 }
 
+static void set_actions_list(PluginData *data)
+{
+    GtkListStore *model = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+    gtk_tree_view_set_model(GTK_TREE_VIEW(data->acts), GTK_TREE_MODEL(model));
+    g_object_unref(model);
+}
+
+static void set_apps_list(PluginData *data)
+{
+    GtkListStore *model = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+    GList *apps = data->cb->get_app_keys(data->config, "*", NULL);
+    GList *l;
+    LXHotkeyApp *app;
+    GtkTreeIter iter;
+
+    for (l = apps; l; l = l->next)
+    {
+        app = l->data;
+        gtk_list_store_insert_with_values(model, &iter, -1, 0, app->exec,
+                                                            1, app->accel1,
+                                                            2, app->accel2, -1);
+    }
+    g_list_free(apps);
+    gtk_tree_view_set_model(GTK_TREE_VIEW(data->apps), GTK_TREE_MODEL(model));
+    g_object_unref(model);
+}
+
 static void module_gtk_run(const gchar *wm, const LXHotkeyPluginInit *cb,
                            gpointer config, GError **error)
 {
@@ -108,12 +155,11 @@ static void module_gtk_run(const gchar *wm, const LXHotkeyPluginInit *cb,
     GtkWidget *win, *menubar;
     GtkToolbar *toolbar;
     GtkBox *vbox;
-    GtkWidget *acts, *apps;
-    GtkNotebook *notebook;
     PluginData data;
-    int i = 0;
 
-    gtk_init(&i, NULL);
+    if (!inited)
+        gtk_init(&inited, NULL);
+    inited = 1;
 
     data.wm = wm;
     data.cb = cb;
@@ -149,25 +195,47 @@ static void module_gtk_run(const gchar *wm, const LXHotkeyPluginInit *cb,
     gtk_box_pack_start(vbox, GTK_WIDGET(toolbar), FALSE, TRUE, 0);
 
     /* notebook - it contains two tabs: Actions and Programs */
-    notebook = (GtkNotebook*)gtk_notebook_new();
-    gtk_notebook_set_scrollable(notebook, TRUE);
-    gtk_container_set_border_width(GTK_CONTAINER(notebook), 0);
+    data.notebook = (GtkNotebook*)gtk_notebook_new();
+    gtk_notebook_set_scrollable(data.notebook, TRUE);
+    gtk_container_set_border_width(GTK_CONTAINER(data.notebook), 0);
 
-    g_signal_connect_after(notebook, "switch-page",
+    g_signal_connect_after(data.notebook, "switch-page",
                            G_CALLBACK(on_notebook_switch_page), &data);
 
-    gtk_box_pack_start(vbox, GTK_WIDGET(notebook), TRUE, TRUE, 0);
+    gtk_box_pack_start(vbox, GTK_WIDGET(data.notebook), TRUE, TRUE, 0);
 
     /* setup notebook */
-    acts = gtk_tree_view_new();
-    //...
-    
-    gtk_notebook_append_page(notebook, acts, gtk_label_new(_("Actions")));
-
-    apps = gtk_tree_view_new();
-    //...
-    
-    gtk_notebook_append_page(notebook, apps, gtk_label_new(_("Programs")));
+    if (cb->get_wm_keys)
+    {
+        data.acts = gtk_tree_view_new();
+        gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(data.acts), 0,
+                                                    _("Action"), gtk_cell_renderer_text_new(),
+                                                    "text", 0, NULL);
+        gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(data.acts), 1,
+                                                    _("Hotkey 1"), gtk_cell_renderer_text_new(),
+                                                    "text", 1, NULL);
+        gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(data.acts), 2,
+                                                    _("Hotkey 2"), gtk_cell_renderer_text_new(),
+                                                    "text", 2, NULL);
+        set_actions_list(&data);
+        gtk_notebook_append_page(data.notebook, data.acts, gtk_label_new(_("Actions")));
+    }
+
+    if (cb->get_app_keys)
+    {
+        data.apps = gtk_tree_view_new();
+        gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(data.apps), 0,
+                                                    _("Command"), gtk_cell_renderer_text_new(),
+                                                    "text", 0, NULL);
+        gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(data.apps), 1,
+                                                    _("Hotkey 1"), gtk_cell_renderer_text_new(),
+                                                    "text", 1, NULL);
+        gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(data.apps), 2,
+                                                    _("Hotkey 2"), gtk_cell_renderer_text_new(),
+                                                    "text", 2, NULL);
+        set_apps_list(&data);
+        gtk_notebook_append_page(data.notebook, data.apps, gtk_label_new(_("Programs")));
+    }
 
     /* and finally run it all */
     gtk_container_add(GTK_CONTAINER(win), GTK_WIDGET(vbox));
@@ -179,9 +247,17 @@ static void module_gtk_alert(GError *error)
 {
 }
 
+static void module_gtk_init(int argc, char **argv)
+{
+    if (!inited)
+        gtk_init(&argc, &argv);
+    inited = 1;
+}
+
 FM_DEFINE_MODULE(lxhotkey_gui, gtk)
 
 LXHotkeyGUIPluginInit fm_module_init_lxhotkey_gui = {
     .run = module_gtk_run,
-    .alert = module_gtk_alert
+    .alert = module_gtk_alert,
+    .init = module_gtk_init
 };
diff --git a/plugins/lxhotkey-gtk.desktop.in b/plugins/lxhotkey-gtk.desktop.in
new file mode 100644 (file)
index 0000000..ef27f21
--- /dev/null
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Type=Application
+Icon=preferences-desktop-keyboard
+_Name=Setup Hot Keys
+_Comment=View and change Window Manager global shortcuts
+_Keywords=hotkey;shortcut;system;settings;
+Categories=SystemSettings;Settings;Core;GTK;
+NotShowIn=GNOME;KDE;XFCE;MATE;
+Exec=lxhotkey --gui=gtk
+StartupNotify=true
+Terminal=false
index 3adc201..b925607 100644 (file)
@@ -926,6 +926,8 @@ static gboolean obcfg_save(gpointer config, GError **error)
             ret = g_file_set_contents(cfg->path, contents, len, error);
         g_free(contents);
     }
+    if (ret)
+        ret = restart_openbox(error);
     return ret;
 }
 
@@ -1183,7 +1185,7 @@ _accel2_bound:
         }
         cfg->actions = g_list_prepend(cfg->actions, act);
     }
-    return restart_openbox(error);
+    return TRUE;
 }
 
 static GList *obcfg_get_app_keys(gpointer config, const char *mask, GError **error)
@@ -1347,7 +1349,7 @@ _accel2_bound:
         }
         cfg->execs = g_list_prepend(cfg->execs, app);
     }
-    return restart_openbox(error);
+    return TRUE;
 }
 
 static GList *obcfg_get_wm_actions(gpointer config, GError **error)
index b2c008d..2d5f965 100644 (file)
@@ -1,3 +1,4 @@
 src/lxhotkey.c
 plugins/openbox.c
 plugins/gtk.c
+plugins/lxhotkey-gtk.desktop.in
index 82948a4..ec0252f 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-10-25 01:16+0300\n"
+"POT-Creation-Date: 2016-10-25 03:56+0300\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,115 +17,115 @@ msgstr ""
 "Content-Type: text/plain; charset=CHARSET\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../src/lxhotkey.c:229
+#: ../src/lxhotkey.c:235
 #, c-format
 msgid "Usage: %s global [<action>]      - show keys bound to action(s)\n"
 msgstr ""
 
-#: ../src/lxhotkey.c:230
+#: ../src/lxhotkey.c:236
 #, c-format
 msgid "       %s global <action> <key>  - bind a key to the action\n"
 msgstr ""
 
-#: ../src/lxhotkey.c:231
+#: ../src/lxhotkey.c:237
 #, c-format
 msgid "       %s app [<exec>]           - show keys bound to exec line\n"
 msgstr ""
 
-#: ../src/lxhotkey.c:232
+#: ../src/lxhotkey.c:238
 #, c-format
 msgid "       %s app <exec> <key>       - bind a key to some exec line\n"
 msgstr ""
 
-#: ../src/lxhotkey.c:233
+#: ../src/lxhotkey.c:239
 #, c-format
 msgid "       %s app <exec> --          - unbind all keys from exec line\n"
 msgstr ""
 
-#: ../src/lxhotkey.c:234
+#: ../src/lxhotkey.c:240
 #, c-format
 msgid "       %s show <key>             - show the action bound to a key\n"
 msgstr ""
 
-#: ../src/lxhotkey.c:235
+#: ../src/lxhotkey.c:241
 #, c-format
 msgid "       %s --gui=<type>           - start with GUI\n"
 msgstr ""
 
-#: ../src/lxhotkey.c:330
+#: ../src/lxhotkey.c:336
 msgid "empty option name."
 msgstr ""
 
-#: ../src/lxhotkey.c:333
+#: ../src/lxhotkey.c:339
 msgid "empty action name."
 msgstr ""
 
-#: ../src/lxhotkey.c:365
+#: ../src/lxhotkey.c:371
 #, c-format
 msgid "no matching option '%s' found for action '%s'."
 msgstr ""
 
-#: ../src/lxhotkey.c:369
+#: ../src/lxhotkey.c:375
 #, c-format
 msgid "action '%s' isn't supported by WM %s."
 msgstr ""
 
-#: ../src/lxhotkey.c:386
+#: ../src/lxhotkey.c:392
 #, c-format
 msgid "value '%s' is not supported for option '%s'."
 msgstr ""
 
-#: ../src/lxhotkey.c:390
+#: ../src/lxhotkey.c:396
 #, c-format
 msgid "value '%s' is not supported for action '%s'."
 msgstr ""
 
-#: ../src/lxhotkey.c:403
+#: ../src/lxhotkey.c:409
 #, c-format
 msgid "action '%s' does not support options."
 msgstr ""
 
-#: ../src/lxhotkey.c:467
+#: ../src/lxhotkey.c:473
 #, c-format
 msgid "LXHotkey: sorry, cannot configure keys remotely.\n"
 msgstr ""
 
-#: ../src/lxhotkey.c:494
+#: ../src/lxhotkey.c:500
 #, c-format
 msgid "Window manager %s isn't supported now, sorry."
 msgstr ""
 
-#: ../src/lxhotkey.c:501
+#: ../src/lxhotkey.c:507
 msgid "Problems loading configuration: "
 msgstr ""
 
-#: ../src/lxhotkey.c:510
+#: ../src/lxhotkey.c:516
 #, c-format
 msgid "GUI type %s currently isn't supported."
 msgstr ""
 
 #. invalid request
-#: ../src/lxhotkey.c:527 ../src/lxhotkey.c:603
+#: ../src/lxhotkey.c:533 ../src/lxhotkey.c:609
 msgid "Invalid request: "
 msgstr ""
 
-#: ../src/lxhotkey.c:537 ../src/lxhotkey.c:615
+#: ../src/lxhotkey.c:543 ../src/lxhotkey.c:621
 msgid "Problems saving configuration: "
 msgstr ""
 
-#: ../src/lxhotkey.c:554
+#: ../src/lxhotkey.c:560
 msgid "ACTION(s)"
 msgstr ""
 
-#: ../src/lxhotkey.c:554 ../src/lxhotkey.c:632
+#: ../src/lxhotkey.c:560 ../src/lxhotkey.c:638
 msgid "KEY(s)"
 msgstr ""
 
-#: ../src/lxhotkey.c:632
+#: ../src/lxhotkey.c:638
 msgid "EXEC"
 msgstr ""
 
-#: ../src/lxhotkey.c:653
+#: ../src/lxhotkey.c:659
 msgid "Requested operation isn't supported."
 msgstr ""
 
@@ -661,3 +661,15 @@ msgstr ""
 #: ../plugins/gtk.c:170
 msgid "Programs"
 msgstr ""
+
+#: ../plugins/lxhotkey-gtk.desktop.in.h:1
+msgid "Setup Hot Keys"
+msgstr ""
+
+#: ../plugins/lxhotkey-gtk.desktop.in.h:2
+msgid "View and change Window Manager global shortcuts"
+msgstr ""
+
+#: ../plugins/lxhotkey-gtk.desktop.in.h:3
+msgid "hotkey;shortcut;system;settings;"
+msgstr ""
index f3416a6..0ed7e51 100644 (file)
@@ -51,9 +51,9 @@ static inline LXHotkeyAttr *lxhotkey_attr_new(void)
     return g_slice_new0(LXHotkeyAttr);
 }
 
-#define free_actions(acts) g_list_free_full(acts, (GDestroyNotify)lkxeys_attr_free)
+#define free_actions(acts) g_list_free_full(acts, (GDestroyNotify)lxkeys_attr_free)
 
-static void lkxeys_attr_free(LXHotkeyAttr *data)
+static void lxkeys_attr_free(LXHotkeyAttr *data)
 {
     g_free(data->name);
     g_list_free_full(data->values, g_free);
@@ -170,6 +170,12 @@ static gchar *get_wm_info(void)
 /* test if we are called from X which is local */
 static gboolean test_X_is_local(void)
 {
+//    const char *display = g_getenv("DISPLAY");
+
+//    if (!display)
+//        return FALSE;
+//    display = strchr(display, ':');
+//    return (display && display[1] == '0');
     return TRUE; // FIXME: TODO!
 }
 
@@ -504,7 +510,11 @@ int main(int argc, char *argv[])
 
     if (do_gui) {
         if (gui_plugin && gui_plugin->t->run)
+        {
+            if (gui_plugin->t->init)
+                gui_plugin->t->init(argc, argv);
             gui_plugin->t->run(wm_name, plugin->t, config, &error);
+        }
         else
             g_set_error(&error, LXKEYS_ERROR, LXKEYS_NOT_SUPPORTED,
                         _("GUI type %s currently isn't supported."), cmd);
index 4730a9f..62b3e8c 100644 (file)
@@ -106,7 +106,7 @@ typedef struct {
 /**
  * LXHotkeyPluginInit:
  * @load: callback to (re)load bindings from WM configuration
- * @save: callback to save bindings to WM configuration
+ * @save: callback to save bindings to WM configuration and apply them
  * @free: callback to release allocated resources
  * @get_wm_keys: (allow-none): callback to get global keys by provided mask
  * @set_wm_key: (allow-none): callback to set a global key by provided data
@@ -117,7 +117,7 @@ typedef struct {
  *
  * Callbacks @get_wm_keys and @get_app_keys return list which should be freed
  * by caller (transfer container).
- * Callbacks @get_wm_actions and @get_app_actions return list that should be
+ * Callbacks @get_wm_actions and @get_app_options return list that should be
  * not modified nor freed by caller (transfer none).
  * Callback @get_wm_keys returns list of keybindings by @mask which is a shell
  * style pattern for keys.
@@ -187,6 +187,7 @@ typedef struct {
     /*< public >*/
     void (*run)(const gchar *wm, const LXHotkeyPluginInit *cb, gpointer config, GError **error);
     void (*alert)(GError *error);
+    void (*init)(int argc, char **argv);
     /*< private >*/
     gpointer _reserved1;
     gpointer _reserved2;