Merge pull request #59 from flexiondotorg/newtab

Make mate-terminal --tab open a tab when applicable
master-1.22
Stefano Karapetsas 2014-03-09 13:14:22 +01:00
commit 34fb5c3b8e
7 changed files with 178 additions and 29 deletions

View File

@ -219,6 +219,29 @@ terminal_app_get_screen_by_display_name (const char *display_name,
return screen; 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 */ /* Menubar mnemonics settings handling */
static int static int
@ -1688,32 +1711,38 @@ terminal_app_handle_options (TerminalApp *app,
for (lw = options->initial_windows; lw != NULL; lw = lw->next) for (lw = options->initial_windows; lw != NULL; lw = lw->next)
{ {
InitialWindow *iw = lw->data; InitialWindow *iw = lw->data;
TerminalWindow *window; TerminalWindow *window = NULL;
GList *lt; GList *lt;
g_assert (iw->tabs); g_assert (iw->tabs);
/* Create & setup new window */ if ( lw == options->initial_windows && ((InitialTab *)iw->tabs->data)->attach_window )
window = terminal_app_new_window (app, gdk_screen); window = terminal_app_get_current_window(app, gdk_screen, options->initial_workspace);
/* Restored windows shouldn't demand attention; see bug #586308. */ if (!window)
if (iw->source_tag == SOURCE_SESSION) {
terminal_window_set_is_restored (window); /* Create & setup new window */
window = terminal_app_new_window (app, gdk_screen);
if (options->startup_id != NULL) /* Restored windows shouldn't demand attention; see bug #586308. */
gtk_window_set_startup_id (GTK_WINDOW (window), options->startup_id); if (iw->source_tag == SOURCE_SESSION)
terminal_window_set_is_restored (window);
/* Overwrite the default, unique window role set in terminal_window_init */ if (options->startup_id != NULL)
if (iw->role) gtk_window_set_startup_id (GTK_WINDOW (window), options->startup_id);
gtk_window_set_role (GTK_WINDOW (window), iw->role);
if (iw->force_menubar_state) /* Overwrite the default, unique window role set in terminal_window_init */
terminal_window_set_menubar_visible (window, iw->menubar_state); if (iw->role)
gtk_window_set_role (GTK_WINDOW (window), iw->role);
if (iw->start_fullscreen) if (iw->force_menubar_state)
gtk_window_fullscreen (GTK_WINDOW (window)); terminal_window_set_menubar_visible (window, iw->menubar_state);
if (iw->start_maximized)
gtk_window_maximize (GTK_WINDOW (window)); if (iw->start_fullscreen)
gtk_window_fullscreen (GTK_WINDOW (window));
if (iw->start_maximized)
gtk_window_maximize (GTK_WINDOW (window));
}
/* Now add the tabs */ /* Now add the tabs */
for (lt = iw->tabs; lt != NULL; lt = lt->next) 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); terminal_encoding_dialog_show (transient_parent);
} }
/*
* Get the window in the given screen and workspace. If nothing is found,
* a NULL is returned.
*/
TerminalWindow * 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) if (app->windows == NULL)
return 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;
} }
/** /**

View File

@ -115,7 +115,9 @@ TerminalScreen *terminal_app_new_terminal (TerminalApp *app,
char **child_env, char **child_env,
double zoom); 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, void terminal_app_manage_profiles (TerminalApp *app,
GtkWindow *transient_parent); GtkWindow *transient_parent);

View File

@ -51,6 +51,7 @@ initial_tab_new (const char *profile,
it->zoom = 1.0; it->zoom = 1.0;
it->zoom_set = FALSE; it->zoom_set = FALSE;
it->active = FALSE; it->active = FALSE;
it->attach_window = FALSE;
return it; return it;
} }
@ -305,18 +306,22 @@ option_tab_callback (const gchar *option_name,
{ {
TerminalOptions *options = data; TerminalOptions *options = data;
gboolean is_profile_id; gboolean is_profile_id;
InitialWindow *iw;
InitialTab *it;
is_profile_id = g_str_has_suffix (option_name, "-with-profile-internal-id"); is_profile_id = g_str_has_suffix (option_name, "-with-profile-internal-id");
if (options->initial_windows) if (options->initial_windows)
{ {
InitialWindow *iw;
iw = g_list_last (options->initial_windows)->data; iw = g_list_last (options->initial_windows)->data;
iw->tabs = g_list_append (iw->tabs, initial_tab_new (value, is_profile_id)); iw->tabs = g_list_append (iw->tabs, initial_tab_new (value, is_profile_id));
} }
else 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; return TRUE;
} }
@ -707,6 +712,7 @@ terminal_options_parse (const char *working_directory,
options->default_maximize = FALSE; options->default_maximize = FALSE;
options->execute = FALSE; options->execute = FALSE;
options->use_factory = TRUE; options->use_factory = TRUE;
options->initial_workspace = -1;
options->env = g_strdupv (env); options->env = g_strdupv (env);
options->startup_id = g_strdup (startup_id && startup_id[0] ? startup_id : NULL); options->startup_id = g_strdup (startup_id && startup_id[0] ? startup_id : NULL);

View File

@ -53,6 +53,7 @@ typedef struct
char *config_file; char *config_file;
gboolean load_config; gboolean load_config;
gboolean save_config; gboolean save_config;
int initial_workspace;
} TerminalOptions; } TerminalOptions;
typedef struct typedef struct
@ -65,6 +66,7 @@ typedef struct
double zoom; double zoom;
guint zoom_set : 1; guint zoom_set : 1;
guint active : 1; guint active : 1;
guint attach_window : 1;
} InitialTab; } InitialTab;
typedef struct typedef struct

View File

@ -97,6 +97,7 @@ struct _TerminalWindowPrivate
/* Workaround until gtk+ bug #535557 is fixed */ /* Workaround until gtk+ bug #535557 is fixed */
guint icon_title_set : 1; guint icon_title_set : 1;
time_t focus_time;
}; };
#define PROFILE_DATA_KEY "GT::Profile" #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, static gboolean terminal_window_delete_event (GtkWidget *widget,
GdkEvent *event, GdkEvent *event,
gpointer data); gpointer data);
static gboolean terminal_window_focus_in_event (GtkWidget *widget,
GdkEventFocus *event,
gpointer data);
static gboolean notebook_button_press_cb (GtkWidget *notebook, static gboolean notebook_button_press_cb (GtkWidget *notebook,
GdkEventButton *event, GdkEventButton *event,
@ -2136,6 +2140,10 @@ terminal_window_init (TerminalWindow *window)
g_signal_connect (G_OBJECT (window), "delete_event", g_signal_connect (G_OBJECT (window), "delete_event",
G_CALLBACK(terminal_window_delete_event), G_CALLBACK(terminal_window_delete_event),
NULL); NULL);
g_signal_connect (G_OBJECT (window), "focus_in_event",
G_CALLBACK(terminal_window_focus_in_event),
NULL);
#ifdef MATE_ENABLE_DEBUG #ifdef MATE_ENABLE_DEBUG
_TERMINAL_DEBUG_IF (TERMINAL_DEBUG_GEOMETRY) _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); 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 static void
terminal_window_show (GtkWidget *widget) 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_key_file_set_string_list (key_file, group, TERMINAL_CONFIG_WINDOW_PROP_TABS, (const char * const *) tab_names, len);
g_strfreev (tab_names); 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;
}

View File

@ -101,6 +101,9 @@ void terminal_window_save_state (TerminalWindow *window,
GKeyFile *key_file, GKeyFile *key_file,
const char *group); const char *group);
TerminalWindow *terminal_window_get_latest_focused (TerminalWindow *window1,
TerminalWindow *window2);
G_END_DECLS G_END_DECLS
#endif /* TERMINAL_WINDOW_H */ #endif /* TERMINAL_WINDOW_H */

View File

@ -155,12 +155,13 @@ method_call_cb (GDBusConnection *connection,
TerminalOptions *options = NULL; TerminalOptions *options = NULL;
GVariant *v_wd, *v_display, *v_sid, *v_envv, *v_argv; GVariant *v_wd, *v_display, *v_sid, *v_envv, *v_argv;
char *working_directory = NULL, *display_name = NULL, *startup_id = NULL; char *working_directory = NULL, *display_name = NULL, *startup_id = NULL;
int initial_workspace = -1;
char **envv = NULL, **argv = NULL; char **envv = NULL, **argv = NULL;
int argc; int argc;
GError *error = NULL; GError *error = NULL;
g_variant_get (parameters, "(@ay@ay@ay@ay@ay)", g_variant_get (parameters, "(@ay@ay@ay@ayi@ay)",
&v_wd, &v_display, &v_sid, &v_envv, &v_argv); &v_wd, &v_display, &v_sid, &v_envv, &initial_workspace, &v_argv);
working_directory = ay_to_string (v_wd, &error); working_directory = ay_to_string (v_wd, &error);
if (error) if (error)
@ -175,10 +176,12 @@ method_call_cb (GDBusConnection *connection,
argv = ay_to_strv (v_argv, &argc); argv = ay_to_strv (v_argv, &argc);
_terminal_debug_print (TERMINAL_DEBUG_FACTORY, _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)", working_directory ? working_directory : "(null)",
display_name ? display_name : "(null)", display_name ? display_name : "(null)",
startup_id ? startup_id : "(null)"); startup_id ? startup_id : "(null)",
initial_workspace);
options = terminal_options_parse (working_directory, options = terminal_options_parse (working_directory,
display_name, display_name,
@ -190,6 +193,8 @@ method_call_cb (GDBusConnection *connection,
&error, &error,
NULL); NULL);
options->initial_workspace = initial_workspace;
if (options != NULL) if (options != NULL)
{ {
terminal_app_handle_options (terminal_app_get (), options, FALSE /* no resume */, &error); terminal_app_handle_options (terminal_app_get (), options, FALSE /* no resume */, &error);
@ -233,6 +238,7 @@ bus_acquired_cb (GDBusConnection *connection,
"<arg type='ay' name='display_name' direction='in' />" "<arg type='ay' name='display_name' direction='in' />"
"<arg type='ay' name='startup_id' direction='in' />" "<arg type='ay' name='startup_id' direction='in' />"
"<arg type='ay' name='environment' direction='in' />" "<arg type='ay' name='environment' direction='in' />"
"<arg type='i' name='workspace' direction='in' />"
"<arg type='ay' name='arguments' direction='in' />" "<arg type='ay' name='arguments' direction='in' />"
"</method>" "</method>"
"</interface>" "</interface>"
@ -340,8 +346,8 @@ name_lost_cb (GDBusConnection *connection,
_terminal_debug_print (TERMINAL_DEBUG_FACTORY, _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
"Forwarding arguments to existing instance\n"); "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->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->display_name));
g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->startup_id)); 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_builder_add (&builder, "@ay",
g_variant_new_from_data (G_VARIANT_TYPE ("ay"), s, len, TRUE, g_free, s)); 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); string = g_string_new (NULL);
for (i = 0; i < data->argc; ++i) 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); 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 int
main (int argc, char **argv) main (int argc, char **argv)
{ {
@ -610,6 +641,9 @@ main (int argc, char **argv)
data->argv = argv_copy; data->argv = argv_copy;
data->argc = argc_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, owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
data->factory_name, data->factory_name,
G_BUS_NAME_OWNER_FLAGS_NONE, G_BUS_NAME_OWNER_FLAGS_NONE,