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;
}
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;
}
/**

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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 */

View File

@ -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,
"<arg type='ay' name='display_name' direction='in' />"
"<arg type='ay' name='startup_id' direction='in' />"
"<arg type='ay' name='environment' direction='in' />"
"<arg type='i' name='workspace' direction='in' />"
"<arg type='ay' name='arguments' direction='in' />"
"</method>"
"</interface>"
@ -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,