From 5ded52f5e98d60abb903cc9194714a9b293ad482 Mon Sep 17 00:00:00 2001 From: Felipe Barriga Richards Date: Fri, 6 Jan 2017 13:48:20 -0300 Subject: Added hotkey to rename current workspace --- src/50-marco-desktop-key.xml.in | 2 + src/core/keybindings.c | 154 ++++++++++++++++++++++++++++++++++++++++ src/core/util.c | 88 +++++++++++++++++++++++ src/include/all-keybindings.h | 1 + src/include/util.h | 9 +++ src/org.mate.marco.gschema.xml | 5 ++ 6 files changed, 259 insertions(+) diff --git a/src/50-marco-desktop-key.xml.in b/src/50-marco-desktop-key.xml.in index f9e33c30..ade92dd5 100644 --- a/src/50-marco-desktop-key.xml.in +++ b/src/50-marco-desktop-key.xml.in @@ -11,5 +11,7 @@ + + diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 271cf885..5eec52d0 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -38,6 +38,8 @@ #include "effects.h" #include "util.h" +#include + #include #include #include @@ -64,6 +66,8 @@ handler (MetaDisplay *display,\ XEvent *event,\ MetaKeyBinding *binding); #include "all-keybindings.h" +#include "../include/util.h" + #undef keybind /* These can't be bound to anything, but they are used to handle @@ -3466,3 +3470,153 @@ handle_run_terminal (MetaDisplay *display, g_error_free (err); } } + +static gboolean already_displaying_rename_workspace = FALSE; +#define RENAME_WORKSPACE_BUFSIZE 512 + +static gboolean +handle_rename_workspace_callback(GIOChannel *ioc, GIOCondition cond, gpointer data) +{ + meta_topic (META_DEBUG_KEYBINDINGS, "handle_rename_workspace_callback: called.\n"); + gint *workspace_index = data; + + if (!already_displaying_rename_workspace) + { + meta_topic (META_DEBUG_KEYBINDINGS, "handle_rename_workspace_callback: done, already_displaying_rename_workspace=FALSE\n"); + return FALSE; + } + + if (cond & G_IO_HUP) + { + meta_topic (META_DEBUG_KEYBINDINGS, "handle_rename_workspace_callback: done.\n"); + g_free(workspace_index); + already_displaying_rename_workspace = FALSE; + return FALSE; + } + + + if (cond & G_IO_ERR ) + { + meta_warning ("handle_rename_workspace_callback: error. G_IO_ERR.\n"); + g_free(workspace_index); + already_displaying_rename_workspace = FALSE; + return FALSE; + } + + if (cond & G_IO_NVAL ) + { + meta_warning ("handle_rename_workspace_callback: error. G_IO_NVAL.\n"); + g_free(workspace_index); + already_displaying_rename_workspace = FALSE; + return FALSE; + } + + + meta_topic (META_DEBUG_KEYBINDINGS, "handle_rename_workspace_callback: workspace_index=%d\n", *workspace_index); + if (*workspace_index < 0 || *workspace_index > 36) + { + meta_warning ("handle_rename_workspace_callback: invalid workspace_index=%d\n", *workspace_index); + g_free(workspace_index); + already_displaying_rename_workspace = FALSE; + return FALSE; + } + + + if (cond & (!G_IO_IN & !G_IO_PRI)) + { + meta_warning ("handle_rename_workspace_callback: unknown error\n"); + g_free(workspace_index); + already_displaying_rename_workspace = FALSE; + return FALSE; + } + + GIOStatus ret; + + gchar buf[RENAME_WORKSPACE_BUFSIZE]; + gchar clean_buf[RENAME_WORKSPACE_BUFSIZE]; + gsize buf_len = 0; + glong clean_buf_len = 0; + + memset (buf, 0x00, RENAME_WORKSPACE_BUFSIZE); + memset (clean_buf, 0x00, RENAME_WORKSPACE_BUFSIZE); + + ret = g_io_channel_read_chars (ioc, buf, RENAME_WORKSPACE_BUFSIZE, &buf_len, NULL); + + if (buf_len <= 0 || ret != G_IO_STATUS_NORMAL) + { + meta_topic (META_DEBUG_KEYBINDINGS, "handle_rename_workspace_callback: error getting the new name.\n"); + g_free(workspace_index); + already_displaying_rename_workspace = FALSE; + return FALSE; + } + + if (!g_utf8_validate (buf, -1, NULL)) + { + meta_topic (META_DEBUG_KEYBINDINGS, "handle_rename_workspace_callback: the string is not utf-8: %s\n", buf); + g_free(workspace_index); + already_displaying_rename_workspace = FALSE; + return FALSE; + } + + clean_buf_len = g_utf8_strlen (buf, -1); + if (clean_buf_len <= 1) + { + meta_topic (META_DEBUG_KEYBINDINGS, "handle_rename_workspace_callback: invalid name.\n"); + g_free(workspace_index); + already_displaying_rename_workspace = FALSE; + return FALSE; + } + + g_utf8_strncpy (clean_buf, buf, clean_buf_len - 1); + meta_prefs_change_workspace_name(*workspace_index, clean_buf); + already_displaying_rename_workspace = FALSE; + + return TRUE; +} + +static void +handle_rename_workspace(MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + XEvent *event, + MetaKeyBinding *binding) +{ + gchar *window_title, *window_content, *entry_text; + GPid dialog_pid; + + meta_topic (META_DEBUG_KEYBINDINGS, "handle_rename_workspace: called.\n"); + + if (already_displaying_rename_workspace) + { + meta_topic (META_DEBUG_KEYBINDINGS, + "handle_rename_workspace: return, already_displaying_rename_workspace=TRUE.\n"); + return; + } + + window_title = g_strdup_printf (_("Rename Workspace")); + window_content = g_strdup_printf (_("New Workspace Name:")); + + gint *workspace_index = g_malloc (sizeof (gint)); + *workspace_index = meta_workspace_index (screen->active_workspace); + meta_topic (META_DEBUG_KEYBINDINGS, "handle_rename_workspace: workspace_index=%d\n", *workspace_index); + + entry_text = meta_prefs_get_workspace_name(*workspace_index); + dialog_pid = meta_show_entry_dialog (window_content, + workspace_index, + entry_text, + screen->screen_name, + _("OK"), _("Cancel"), + 0, + handle_rename_workspace_callback); + + g_free (window_title); + g_free (window_content); + if (dialog_pid > 0) + { + already_displaying_rename_workspace = TRUE; + } + else + { + g_free(workspace_index); + } +} diff --git a/src/core/util.c b/src/core/util.c index 1cb7793c..a30707a7 100644 --- a/src/core/util.c +++ b/src/core/util.c @@ -635,5 +635,93 @@ meta_show_dialog (const char *type, return child_pid; } + +GPid +meta_show_entry_dialog(const char *message, + gint *active_workspace_id, + const char *entry_text, + const char *display, + const char *ok_text, + const char *cancel_text, + const int transient_for, + const GIOFunc stdio_func_cb) +{ + meta_topic (META_DEBUG_KEYBINDINGS, + "meta_show_entry_dialog: called. active_workspace_id=%d message=%s entry_text=%s\n", + *active_workspace_id, message, entry_text); + + GError *error = NULL; + int i = 0; + GPid child_pid; + gint stdout_fd; + const char **argvl = g_malloc (sizeof (char *) * (17)); + + argvl[i++] = "zenity"; + argvl[i++] = "--entry"; + argvl[i++] = "--display"; + argvl[i++] = display; + argvl[i++] = "--class"; + argvl[i++] = "marco-dialog"; + argvl[i++] = "--title"; + /* Translators: This is the title used on dialog boxes */ + argvl[i++] = _ ("Marco"); + argvl[i++] = "--text"; + argvl[i++] = message; + + if (entry_text) + { + argvl[i++] = "--entry-text"; + argvl[i++] = entry_text; + } + + if (ok_text) + { + argvl[i++] = "--ok-label"; + argvl[i++] = ok_text; + } + + if (cancel_text) + { + argvl[i++] = "--cancel-label"; + argvl[i++] = cancel_text; + } + argvl[i] = NULL; + + + unsetenv ("WINDOWID"); /* start in current workspace */ + g_spawn_async_with_pipes ( + "/", + (gchar **) argvl, + NULL, + (GSpawnFlags) G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, + NULL, + NULL, + &child_pid, + NULL, + &stdout_fd, + NULL, + &error + ); + + g_free (argvl); + + if (error) + { + meta_warning ("%s\n", error->message); + g_error_free (error); + child_pid = -1; + } + else + { + GIOChannel *ioc = g_io_channel_unix_new(stdout_fd); + g_io_channel_set_encoding(ioc, NULL, NULL); + g_io_channel_set_buffered (ioc, FALSE); + g_io_channel_set_close_on_unref (ioc, TRUE); + g_io_add_watch(ioc, G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP | G_IO_NVAL, stdio_func_cb, active_workspace_id); + g_io_channel_unref(ioc); + } + + return child_pid; +} /* eof util.c */ diff --git a/src/include/all-keybindings.h b/src/include/all-keybindings.h index a26720a1..b236823c 100644 --- a/src/include/all-keybindings.h +++ b/src/include/all-keybindings.h @@ -187,6 +187,7 @@ keybind (run-command-screenshot, handle_run_command, 32, 0) keybind (run-command-window-screenshot, handle_run_command, 33, 0) keybind (run-command-terminal, handle_run_terminal, 0, 0) +keybind (rename-workspace, handle_rename_workspace, 0, 0) /* No description because this is undocumented */ keybind (set-spew-mark, handle_set_spew_mark, 0, 0) diff --git a/src/include/util.h b/src/include/util.h index ba6a2754..545357f8 100644 --- a/src/include/util.h +++ b/src/include/util.h @@ -108,6 +108,15 @@ GPid meta_show_dialog (const char *type, GSList *columns, GSList *entries); +GPid +meta_show_entry_dialog (const char *message, + gint *active_workspace_id, + const char *entry_text, + const char *display, + const char *ok_text, + const char *cancel_text, + const int transient_for, + const GIOFunc stdio_func_cb); /* To disable verbose mode, we make these functions into no-ops */ #ifdef WITH_VERBOSE_MODE diff --git a/src/org.mate.marco.gschema.xml b/src/org.mate.marco.gschema.xml index ed6f523b..835abebe 100644 --- a/src/org.mate.marco.gschema.xml +++ b/src/org.mate.marco.gschema.xml @@ -622,6 +622,11 @@ Run a terminal The format looks like "<Control>a" or "<Shift><Alt>F1". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as "<Ctl>" and "<Ctrl>". If you set the option to the special string "disabled", then there will be no keybinding for this action. + + 'disabled' + Rename current workspace + The format looks like "<Control>a" or "<Shift><Alt>F1". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as "<Ctl>" and "<Ctrl>". If you set the option to the special string "disabled", then there will be no keybinding for this action. + -- cgit v1.2.1