diff --git a/src/terminal-app.c b/src/terminal-app.c
index caf3533..71d14ee 100644
--- a/src/terminal-app.c
+++ b/src/terminal-app.c
@@ -219,6 +219,29 @@ terminal_app_get_screen_by_display_name (const char *display_name,
return screen;
}
+static int
+terminal_app_get_workspace_for_window (TerminalWindow *window)
+{
+ int ret = -1;
+ guchar *data = NULL;
+ GdkAtom atom;
+ GdkAtom cardinal_atom;
+
+ atom = gdk_atom_intern_static_string ("_NET_WM_DESKTOP");
+ cardinal_atom = gdk_atom_intern_static_string ("CARDINAL");
+
+ gdk_property_get (gtk_widget_get_window(GTK_WIDGET(window)),
+ atom, cardinal_atom, 0, 8, FALSE,
+ NULL, NULL, NULL, &data);
+
+ if (data)
+ ret = *(int *)data;
+
+ g_free (data);
+ return ret;
+}
+
+
/* Menubar mnemonics settings handling */
static int
@@ -1688,32 +1711,38 @@ terminal_app_handle_options (TerminalApp *app,
for (lw = options->initial_windows; lw != NULL; lw = lw->next)
{
InitialWindow *iw = lw->data;
- TerminalWindow *window;
+ TerminalWindow *window = NULL;
GList *lt;
g_assert (iw->tabs);
- /* Create & setup new window */
- window = terminal_app_new_window (app, gdk_screen);
+ if ( lw == options->initial_windows && ((InitialTab *)iw->tabs->data)->attach_window )
+ window = terminal_app_get_current_window(app, gdk_screen, options->initial_workspace);
- /* Restored windows shouldn't demand attention; see bug #586308. */
- if (iw->source_tag == SOURCE_SESSION)
- terminal_window_set_is_restored (window);
+ if (!window)
+ {
+ /* Create & setup new window */
+ window = terminal_app_new_window (app, gdk_screen);
- if (options->startup_id != NULL)
- gtk_window_set_startup_id (GTK_WINDOW (window), options->startup_id);
+ /* Restored windows shouldn't demand attention; see bug #586308. */
+ if (iw->source_tag == SOURCE_SESSION)
+ terminal_window_set_is_restored (window);
- /* Overwrite the default, unique window role set in terminal_window_init */
- if (iw->role)
- gtk_window_set_role (GTK_WINDOW (window), iw->role);
+ if (options->startup_id != NULL)
+ gtk_window_set_startup_id (GTK_WINDOW (window), options->startup_id);
- if (iw->force_menubar_state)
- terminal_window_set_menubar_visible (window, iw->menubar_state);
+ /* Overwrite the default, unique window role set in terminal_window_init */
+ if (iw->role)
+ gtk_window_set_role (GTK_WINDOW (window), iw->role);
- if (iw->start_fullscreen)
- gtk_window_fullscreen (GTK_WINDOW (window));
- if (iw->start_maximized)
- gtk_window_maximize (GTK_WINDOW (window));
+ if (iw->force_menubar_state)
+ terminal_window_set_menubar_visible (window, iw->menubar_state);
+
+ if (iw->start_fullscreen)
+ gtk_window_fullscreen (GTK_WINDOW (window));
+ if (iw->start_maximized)
+ gtk_window_maximize (GTK_WINDOW (window));
+ }
/* Now add the tabs */
for (lt = iw->tabs; lt != NULL; lt = lt->next)
@@ -1842,13 +1871,41 @@ terminal_app_edit_encodings (TerminalApp *app,
terminal_encoding_dialog_show (transient_parent);
}
+/*
+* Get the window in the given screen and workspace. If nothing is found,
+* a NULL is returned.
+*/
TerminalWindow *
-terminal_app_get_current_window (TerminalApp *app)
+terminal_app_get_current_window (TerminalApp *app,
+ GdkScreen *from_screen,
+ int workspace)
{
+ GList *res = NULL;
+ TerminalWindow *ret = NULL;
+
if (app->windows == NULL)
return NULL;
- return g_list_last (app->windows)->data;
+ res = g_list_last (app->windows);
+
+ g_assert (from_screen != NULL);
+
+ while (res)
+ {
+ int win_workspace;
+ if (gtk_window_get_screen(GTK_WINDOW(res->data)) != from_screen)
+ continue;
+
+ win_workspace = terminal_app_get_workspace_for_window(res->data);
+
+ /* Same workspace or if the window is set to show up on all workspaces */
+ if (win_workspace == workspace || win_workspace == -1)
+ ret = terminal_window_get_latest_focused (ret, TERMINAL_WINDOW(res->data));
+
+ res = g_list_previous (res);
+ }
+
+ return ret;
}
/**
diff --git a/src/terminal-app.h b/src/terminal-app.h
index 39c2ad1..70a0665 100644
--- a/src/terminal-app.h
+++ b/src/terminal-app.h
@@ -115,7 +115,9 @@ TerminalScreen *terminal_app_new_terminal (TerminalApp *app,
char **child_env,
double zoom);
-TerminalWindow *terminal_app_get_current_window (TerminalApp *app);
+TerminalWindow *terminal_app_get_current_window (TerminalApp *app,
+ GdkScreen *screen,
+ int curr_workspace);
void terminal_app_manage_profiles (TerminalApp *app,
GtkWindow *transient_parent);
diff --git a/src/terminal-options.c b/src/terminal-options.c
index 6881b67..ce41055 100644
--- a/src/terminal-options.c
+++ b/src/terminal-options.c
@@ -51,6 +51,7 @@ initial_tab_new (const char *profile,
it->zoom = 1.0;
it->zoom_set = FALSE;
it->active = FALSE;
+ it->attach_window = FALSE;
return it;
}
@@ -305,18 +306,22 @@ option_tab_callback (const gchar *option_name,
{
TerminalOptions *options = data;
gboolean is_profile_id;
+ InitialWindow *iw;
+ InitialTab *it;
is_profile_id = g_str_has_suffix (option_name, "-with-profile-internal-id");
if (options->initial_windows)
{
- InitialWindow *iw;
-
iw = g_list_last (options->initial_windows)->data;
iw->tabs = g_list_append (iw->tabs, initial_tab_new (value, is_profile_id));
}
else
- add_new_window (options, value, is_profile_id);
+ {
+ iw = add_new_window (options, value, is_profile_id);
+ it = g_list_last(iw->tabs)->data;
+ it->attach_window = TRUE;
+ }
return TRUE;
}
@@ -707,6 +712,7 @@ terminal_options_parse (const char *working_directory,
options->default_maximize = FALSE;
options->execute = FALSE;
options->use_factory = TRUE;
+ options->initial_workspace = -1;
options->env = g_strdupv (env);
options->startup_id = g_strdup (startup_id && startup_id[0] ? startup_id : NULL);
diff --git a/src/terminal-options.h b/src/terminal-options.h
index cbada18..20f9a3f 100644
--- a/src/terminal-options.h
+++ b/src/terminal-options.h
@@ -53,6 +53,7 @@ typedef struct
char *config_file;
gboolean load_config;
gboolean save_config;
+ int initial_workspace;
} TerminalOptions;
typedef struct
@@ -65,6 +66,7 @@ typedef struct
double zoom;
guint zoom_set : 1;
guint active : 1;
+ guint attach_window : 1;
} InitialTab;
typedef struct
diff --git a/src/terminal-window.c b/src/terminal-window.c
index 43333bf..d15a90c 100644
--- a/src/terminal-window.c
+++ b/src/terminal-window.c
@@ -97,6 +97,7 @@ struct _TerminalWindowPrivate
/* Workaround until gtk+ bug #535557 is fixed */
guint icon_title_set : 1;
+ time_t focus_time;
};
#define PROFILE_DATA_KEY "GT::Profile"
@@ -139,6 +140,9 @@ static gboolean terminal_window_state_event (GtkWidget *widget,
static gboolean terminal_window_delete_event (GtkWidget *widget,
GdkEvent *event,
gpointer data);
+static gboolean terminal_window_focus_in_event (GtkWidget *widget,
+ GdkEventFocus *event,
+ gpointer data);
static gboolean notebook_button_press_cb (GtkWidget *notebook,
GdkEventButton *event,
@@ -2136,6 +2140,10 @@ terminal_window_init (TerminalWindow *window)
g_signal_connect (G_OBJECT (window), "delete_event",
G_CALLBACK(terminal_window_delete_event),
NULL);
+ g_signal_connect (G_OBJECT (window), "focus_in_event",
+ G_CALLBACK(terminal_window_focus_in_event),
+ NULL);
+
#ifdef MATE_ENABLE_DEBUG
_TERMINAL_DEBUG_IF (TERMINAL_DEBUG_GEOMETRY)
{
@@ -2383,6 +2391,20 @@ terminal_window_delete_event (GtkWidget *widget,
return confirm_close_window_or_tab (TERMINAL_WINDOW (widget), NULL);
}
+static gboolean
+terminal_window_focus_in_event (GtkWidget *widget,
+ GdkEventFocus *event,
+ gpointer data)
+{
+ TerminalWindow *window = TERMINAL_WINDOW (widget);
+ TerminalWindowPrivate *priv = window->priv;
+
+ if (event->in)
+ priv->focus_time = time(NULL);
+
+ return FALSE;
+}
+
static void
terminal_window_show (GtkWidget *widget)
{
@@ -4264,3 +4286,26 @@ terminal_window_save_state (TerminalWindow *window,
g_key_file_set_string_list (key_file, group, TERMINAL_CONFIG_WINDOW_PROP_TABS, (const char * const *) tab_names, len);
g_strfreev (tab_names);
}
+
+
+TerminalWindow *
+terminal_window_get_latest_focused (TerminalWindow *window1,
+ TerminalWindow *window2)
+{
+ TerminalWindowPrivate *priv1 = NULL;
+ TerminalWindowPrivate *priv2 = NULL;
+
+ if (!window1)
+ return window2;
+
+ if (!window2)
+ return window1;
+
+ priv1 = window1->priv;
+ priv2 = window2->priv;
+
+ if (priv2->focus_time > priv1->focus_time)
+ return window2;
+
+ return window1;
+}
diff --git a/src/terminal-window.h b/src/terminal-window.h
index d00f825..0e7b464 100644
--- a/src/terminal-window.h
+++ b/src/terminal-window.h
@@ -101,6 +101,9 @@ void terminal_window_save_state (TerminalWindow *window,
GKeyFile *key_file,
const char *group);
+TerminalWindow *terminal_window_get_latest_focused (TerminalWindow *window1,
+ TerminalWindow *window2);
+
G_END_DECLS
#endif /* TERMINAL_WINDOW_H */
diff --git a/src/terminal.c b/src/terminal.c
index 22c7813..4bb7de3 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -155,12 +155,13 @@ method_call_cb (GDBusConnection *connection,
TerminalOptions *options = NULL;
GVariant *v_wd, *v_display, *v_sid, *v_envv, *v_argv;
char *working_directory = NULL, *display_name = NULL, *startup_id = NULL;
+ int initial_workspace = -1;
char **envv = NULL, **argv = NULL;
int argc;
GError *error = NULL;
- g_variant_get (parameters, "(@ay@ay@ay@ay@ay)",
- &v_wd, &v_display, &v_sid, &v_envv, &v_argv);
+ g_variant_get (parameters, "(@ay@ay@ay@ayi@ay)",
+ &v_wd, &v_display, &v_sid, &v_envv, &initial_workspace, &v_argv);
working_directory = ay_to_string (v_wd, &error);
if (error)
@@ -175,10 +176,12 @@ method_call_cb (GDBusConnection *connection,
argv = ay_to_strv (v_argv, &argc);
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
- "Factory invoked with working-dir='%s' display='%s' startup-id='%s'\n",
+ "Factory invoked with working-dir='%s' display='%s' startup-id='%s'"
+ "workspace='%d'\n",
working_directory ? working_directory : "(null)",
display_name ? display_name : "(null)",
- startup_id ? startup_id : "(null)");
+ startup_id ? startup_id : "(null)",
+ initial_workspace);
options = terminal_options_parse (working_directory,
display_name,
@@ -190,6 +193,8 @@ method_call_cb (GDBusConnection *connection,
&error,
NULL);
+ options->initial_workspace = initial_workspace;
+
if (options != NULL)
{
terminal_app_handle_options (terminal_app_get (), options, FALSE /* no resume */, &error);
@@ -233,6 +238,7 @@ bus_acquired_cb (GDBusConnection *connection,
""
""
""
+ ""
""
""
""
@@ -340,8 +346,8 @@ name_lost_cb (GDBusConnection *connection,
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
"Forwarding arguments to existing instance\n");
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ayayayayay)"));
-
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ayayayayiay)"));
+
g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->default_working_dir));
g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->display_name));
g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->startup_id));
@@ -368,6 +374,8 @@ name_lost_cb (GDBusConnection *connection,
g_variant_builder_add (&builder, "@ay",
g_variant_new_from_data (G_VARIANT_TYPE ("ay"), s, len, TRUE, g_free, s));
+ g_variant_builder_add (&builder, "@i", g_variant_new_int32 (data->options->initial_workspace));
+
string = g_string_new (NULL);
for (i = 0; i < data->argc; ++i)
@@ -510,6 +518,29 @@ get_factory_name_for_display (const char *display_name)
return g_string_free (name, FALSE);
}
+static int
+get_initial_workspace (void)
+{
+ int ret = -1;
+ GdkWindow *window;
+ guchar *data = NULL;
+ GdkAtom atom;
+ GdkAtom cardinal_atom;
+
+ g_type_init ();
+
+ window = gdk_get_default_root_window();
+
+ atom = gdk_atom_intern_static_string ("_NET_CURRENT_DESKTOP");
+ cardinal_atom = gdk_atom_intern_static_string ("CARDINAL");
+
+ gdk_property_get (window, atom, cardinal_atom, 0, 8, FALSE, NULL, NULL, NULL, &data);
+
+ ret = *(int *)data;
+ g_free (data);
+ return ret;
+}
+
int
main (int argc, char **argv)
{
@@ -610,6 +641,9 @@ main (int argc, char **argv)
data->argv = argv_copy;
data->argc = argc_copy;
+ gtk_init(&argc, &argv);
+ options->initial_workspace = get_initial_workspace ();
+
owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
data->factory_name,
G_BUS_NAME_OWNER_FLAGS_NONE,