diff options
| -rw-r--r-- | src/50-marco-desktop-key.xml.in | 2 | ||||
| -rw-r--r-- | src/core/keybindings.c | 154 | ||||
| -rw-r--r-- | src/core/util.c | 88 | ||||
| -rw-r--r-- | src/include/all-keybindings.h | 1 | ||||
| -rw-r--r-- | src/include/util.h | 9 | ||||
| -rw-r--r-- | src/org.mate.marco.gschema.xml | 5 | 
6 files changed, 259 insertions, 0 deletions
| 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 @@  	<KeyListEntry name="run-command-terminal" _description="Run a terminal" /> +	<KeyListEntry name="rename-workspace" _description="Rename Current Workspace" /> +  </KeyListEntries> 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 <gio/gio.h> +  #include <X11/keysym.h>  #include <string.h>  #include <stdio.h> @@ -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 (_("<tt>Rename Workspace</tt>")); +  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 @@        <summary>Run a terminal</summary>        <description>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.</description>      </key> +    <key name="rename-workspace" type="s"> +      <default>'disabled'</default> +      <summary>Rename current workspace</summary> +      <description>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.</description> +    </key>    </schema>    <schema id="org.mate.Marco.keybinding-commands" path="/org/mate/marco/keybinding-commands/"> | 
