From 99c679423364d78903d006b74d804482cbed4f81 Mon Sep 17 00:00:00 2001 From: konsolebox Date: Fri, 8 Jul 2016 14:19:17 +0800 Subject: [PATCH 1/2] Add '--no-new-instance' option. This would allow us to force Geany to not open a new instance even if no file arguments are passed in the command-line. Some tweaks were also added so that the current instance window would activate itself even if no new file arguments are specified whenever this option is used. --- doc/geany.1.in | 2 ++ doc/geany.txt | 3 +++ src/libmain.c | 32 ++++++++++++++++++++++++++------ src/main.h | 2 +- src/socket.c | 35 +++++++++++++++++++---------------- src/ui_utils.c | 2 +- 6 files changed, 52 insertions(+), 24 deletions(-) diff --git a/doc/geany.1.in b/doc/geany.1.in index 8c3cea88ae..d177c919ec 100644 --- a/doc/geany.1.in +++ b/doc/geany.1.in @@ -40,6 +40,8 @@ Don't preprocess C/C++ files when generating tags. .IP "\fB-i\fP, \fB\-\-new-instance\fP " 10 Don't open files in a running instance, force opening a new instance. Only available if Geany was compiled with support for Sockets. +.IP "\fB-I\fP, \fB\-\-no-new-instance\fP " 10 +Force not opening a new instance even if no file argument is passed. .IP "\fB-l\fP, \fB\-\-line\fP " 10 Set initial line number for the first opened file. .IP "\fB\fP \fB\-\-list\-documents\fP " 10 diff --git a/doc/geany.txt b/doc/geany.txt index bf007c2e14..f1c2ebf0b0 100644 --- a/doc/geany.txt +++ b/doc/geany.txt @@ -283,6 +283,9 @@ Short option Long option Function a new instance. Only available if Geany was compiled with support for Sockets. +-I --no-new-instance Force not opening a new instance even if no file argument + is passed. + -l --line Set initial line number for the first opened file. *none* --list-documents Return a list of open documents in a running Geany diff --git a/src/libmain.c b/src/libmain.c index fe4f377259..0e0f4a588e 100644 --- a/src/libmain.c +++ b/src/libmain.c @@ -112,6 +112,25 @@ static gboolean no_plugins = FALSE; #endif static gboolean dummy = FALSE; + +gboolean new_instance_arg_callback(const gchar *option_name, const gchar *value, gpointer data, GError **error) +{ + gint len = strlen(option_name); + + if (strncmp(option_name, "-i", len) == 0 || strncmp(option_name, "--new-instance", len) == 0 ) + cl_options.new_instance = 1; + else if (strncmp(option_name, "-I", len) == 0 || strncmp(option_name, "--no-new-instance", len) == 0 ) + cl_options.new_instance = -1; + else + { + g_set_error(error, G_OPTION_ERROR, 64, "Fatal error: Unexpected mismatch in any of the options in callback function for '--new-instance' and '--no-new-instance'"); + return FALSE; + } + + return TRUE; +} + + /* in alphabetical order of short options */ static GOptionEntry entries[] = { @@ -121,7 +140,8 @@ static GOptionEntry entries[] = { "generate-tags", 'g', 0, G_OPTION_ARG_NONE, &generate_tags, N_("Generate global tags file (see documentation)"), NULL }, { "no-preprocessing", 'P', 0, G_OPTION_ARG_NONE, &no_preprocessing, N_("Don't preprocess C/C++ files when generating tags file"), NULL }, #ifdef HAVE_SOCKET - { "new-instance", 'i', 0, G_OPTION_ARG_NONE, &cl_options.new_instance, N_("Don't open files in a running instance, force opening a new instance"), NULL }, + { "new-instance", 'i', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, new_instance_arg_callback, N_("Don't open files in a running instance, force opening a new instance"), NULL }, + { "no-new-instance", 'I', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, new_instance_arg_callback, N_("Force not opening a new instance even if no file argument is passed"), NULL }, { "socket-file", 0, 0, G_OPTION_ARG_FILENAME, &cl_options.socket_filename, N_("Use this socket filename for communication with a running Geany instance"), NULL }, { "list-documents", 0, 0, G_OPTION_ARG_NONE, &cl_options.list_documents, N_("Return a list of open documents in a running Geany instance"), NULL }, #endif @@ -505,7 +525,7 @@ static void parse_command_line_options(gint *argc, gchar ***argv) GError *error = NULL; GOptionContext *context; gint i; - CommandLineOptions def_clo = {FALSE, NULL, TRUE, -1, -1, FALSE, FALSE, FALSE}; + CommandLineOptions def_clo = {0, NULL, TRUE, -1, -1, FALSE, FALSE, FALSE}; /* first initialise cl_options fields with default values */ cl_options = def_clo; @@ -604,7 +624,7 @@ static void parse_command_line_options(gint *argc, gchar ***argv) } #ifdef HAVE_SOCKET - socket_info.ignore_socket = cl_options.new_instance; + socket_info.ignore_socket = cl_options.new_instance == 1 ? TRUE : FALSE; if (cl_options.socket_filename) { socket_info.file_name = cl_options.socket_filename; @@ -930,7 +950,7 @@ static void load_startup_files(gint argc, gchar **argv) * 2. --no-session is not specified. * 3. We are a primary instance. * Has no effect if a CL project is loaded and using project-based session files. */ - if (prefs.load_session && cl_options.load_session && !cl_options.new_instance) + if (prefs.load_session && cl_options.load_session && cl_options.new_instance != 1) { if (app->project == NULL) load_session_project_file(); @@ -1078,7 +1098,7 @@ gint main_lib(gint argc, gchar **argv) socket_info.lock_socket = socket_init(argc, argv); /* Quit if filenames were sent to first instance or the list of open * documents has been printed */ - if ((socket_info.lock_socket == -2 /* socket exists */ && argc > 1) || + if ((socket_info.lock_socket == -2 /* socket exists */ && (argc > 1 || cl_options.new_instance == -1)) || cl_options.list_documents) { socket_finalize(); @@ -1094,7 +1114,7 @@ gint main_lib(gint argc, gchar **argv) else if (socket_info.lock_socket == -2 /* socket already exists */) { socket_info.ignore_socket = TRUE; - cl_options.new_instance = TRUE; + cl_options.new_instance = 1; } } #endif diff --git a/src/main.h b/src/main.h index f2babac344..09ccfc73c0 100644 --- a/src/main.h +++ b/src/main.h @@ -38,7 +38,7 @@ gboolean main_is_realized(void); typedef struct { - gboolean new_instance; + gint new_instance; gchar *socket_filename; gboolean load_session; gint goto_line; diff --git a/src/socket.c b/src/socket.c index 5e4aa4b8c7..213ed1189c 100644 --- a/src/socket.c +++ b/src/socket.c @@ -129,25 +129,28 @@ static void send_open_command(gint sock, gint argc, gchar **argv) { gint i; - g_return_if_fail(argc > 1); + g_return_if_fail(argc > 1 || cl_options.new_instance == -1); geany_debug("using running instance of Geany"); - if (cl_options.goto_line >= 0) + if (argc > 1) { - gchar *line = g_strdup_printf("%d\n", cl_options.goto_line); - socket_fd_write_all(sock, "line\n", 5); - socket_fd_write_all(sock, line, strlen(line)); - socket_fd_write_all(sock, ".\n", 2); - g_free(line); - } + if (cl_options.goto_line >= 0) + { + gchar *line = g_strdup_printf("%d\n", cl_options.goto_line); + socket_fd_write_all(sock, "line\n", 5); + socket_fd_write_all(sock, line, strlen(line)); + socket_fd_write_all(sock, ".\n", 2); + g_free(line); + } - if (cl_options.goto_column >= 0) - { - gchar *col = g_strdup_printf("%d\n", cl_options.goto_column); - socket_fd_write_all(sock, "column\n", 7); - socket_fd_write_all(sock, col, strlen(col)); - socket_fd_write_all(sock, ".\n", 2); - g_free(col); + if (cl_options.goto_column >= 0) + { + gchar *col = g_strdup_printf("%d\n", cl_options.goto_column); + socket_fd_write_all(sock, "column\n", 7); + socket_fd_write_all(sock, col, strlen(col)); + socket_fd_write_all(sock, ".\n", 2); + g_free(col); + } } if (cl_options.readonly) /* append "ro" to denote readonly status for new docs */ @@ -325,7 +328,7 @@ gint socket_init(gint argc, gchar **argv) SetForegroundWindow(hwnd); #endif /* now we send the command line args */ - if (argc > 1) + if (argc > 1 || cl_options.new_instance == -1) { send_open_command(sock, argc, argv); } diff --git a/src/ui_utils.c b/src/ui_utils.c index 702a3453ae..bbe87cad62 100644 --- a/src/ui_utils.c +++ b/src/ui_utils.c @@ -403,7 +403,7 @@ void ui_set_window_title(GeanyDocument *doc) g_string_append(str, "] - "); } g_string_append(str, "Geany"); - if (cl_options.new_instance) + if (cl_options.new_instance == 1) { g_string_append(str, _(" (new instance)")); } From bb463d6320ba0f7776a2fd15cb43e1e9c99195f3 Mon Sep 17 00:00:00 2001 From: konsolebox Date: Fri, 8 Jul 2016 20:20:09 +0800 Subject: [PATCH 2/2] Use an enum named NewInstanceMode instead of gint for cl_options.new_instance. Also renamed new_instance to new_instance_mode to make it more sensible. --- src/libmain.c | 20 ++++++++++---------- src/main.h | 9 ++++++++- src/socket.c | 4 ++-- src/ui_utils.c | 2 +- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/libmain.c b/src/libmain.c index 0e0f4a588e..cf4db51407 100644 --- a/src/libmain.c +++ b/src/libmain.c @@ -113,14 +113,14 @@ static gboolean no_plugins = FALSE; static gboolean dummy = FALSE; -gboolean new_instance_arg_callback(const gchar *option_name, const gchar *value, gpointer data, GError **error) +gboolean new_instance_mode_arg_callback(const gchar *option_name, const gchar *value, gpointer data, GError **error) { gint len = strlen(option_name); if (strncmp(option_name, "-i", len) == 0 || strncmp(option_name, "--new-instance", len) == 0 ) - cl_options.new_instance = 1; + cl_options.new_instance_mode = NEW_INSTANCE_ENABLED; else if (strncmp(option_name, "-I", len) == 0 || strncmp(option_name, "--no-new-instance", len) == 0 ) - cl_options.new_instance = -1; + cl_options.new_instance_mode = NEW_INSTANCE_EXPLICITLY_DISABLED; else { g_set_error(error, G_OPTION_ERROR, 64, "Fatal error: Unexpected mismatch in any of the options in callback function for '--new-instance' and '--no-new-instance'"); @@ -140,8 +140,8 @@ static GOptionEntry entries[] = { "generate-tags", 'g', 0, G_OPTION_ARG_NONE, &generate_tags, N_("Generate global tags file (see documentation)"), NULL }, { "no-preprocessing", 'P', 0, G_OPTION_ARG_NONE, &no_preprocessing, N_("Don't preprocess C/C++ files when generating tags file"), NULL }, #ifdef HAVE_SOCKET - { "new-instance", 'i', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, new_instance_arg_callback, N_("Don't open files in a running instance, force opening a new instance"), NULL }, - { "no-new-instance", 'I', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, new_instance_arg_callback, N_("Force not opening a new instance even if no file argument is passed"), NULL }, + { "new-instance", 'i', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, new_instance_mode_arg_callback, N_("Don't open files in a running instance, force opening a new instance"), NULL }, + { "no-new-instance", 'I', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, new_instance_mode_arg_callback, N_("Force not opening a new instance even if no file argument is passed"), NULL }, { "socket-file", 0, 0, G_OPTION_ARG_FILENAME, &cl_options.socket_filename, N_("Use this socket filename for communication with a running Geany instance"), NULL }, { "list-documents", 0, 0, G_OPTION_ARG_NONE, &cl_options.list_documents, N_("Return a list of open documents in a running Geany instance"), NULL }, #endif @@ -525,7 +525,7 @@ static void parse_command_line_options(gint *argc, gchar ***argv) GError *error = NULL; GOptionContext *context; gint i; - CommandLineOptions def_clo = {0, NULL, TRUE, -1, -1, FALSE, FALSE, FALSE}; + CommandLineOptions def_clo = {NEW_INSTANCE_DISABLED, NULL, TRUE, -1, -1, FALSE, FALSE, FALSE}; /* first initialise cl_options fields with default values */ cl_options = def_clo; @@ -624,7 +624,7 @@ static void parse_command_line_options(gint *argc, gchar ***argv) } #ifdef HAVE_SOCKET - socket_info.ignore_socket = cl_options.new_instance == 1 ? TRUE : FALSE; + socket_info.ignore_socket = cl_options.new_instance_mode == NEW_INSTANCE_ENABLED ? TRUE : FALSE; if (cl_options.socket_filename) { socket_info.file_name = cl_options.socket_filename; @@ -950,7 +950,7 @@ static void load_startup_files(gint argc, gchar **argv) * 2. --no-session is not specified. * 3. We are a primary instance. * Has no effect if a CL project is loaded and using project-based session files. */ - if (prefs.load_session && cl_options.load_session && cl_options.new_instance != 1) + if (prefs.load_session && cl_options.load_session && cl_options.new_instance_mode != NEW_INSTANCE_ENABLED) { if (app->project == NULL) load_session_project_file(); @@ -1098,7 +1098,7 @@ gint main_lib(gint argc, gchar **argv) socket_info.lock_socket = socket_init(argc, argv); /* Quit if filenames were sent to first instance or the list of open * documents has been printed */ - if ((socket_info.lock_socket == -2 /* socket exists */ && (argc > 1 || cl_options.new_instance == -1)) || + if ((socket_info.lock_socket == -2 /* socket exists */ && (argc > 1 || cl_options.new_instance_mode == NEW_INSTANCE_EXPLICITLY_DISABLED)) || cl_options.list_documents) { socket_finalize(); @@ -1114,7 +1114,7 @@ gint main_lib(gint argc, gchar **argv) else if (socket_info.lock_socket == -2 /* socket already exists */) { socket_info.ignore_socket = TRUE; - cl_options.new_instance = 1; + cl_options.new_instance_mode = NEW_INSTANCE_ENABLED; } } #endif diff --git a/src/main.h b/src/main.h index 09ccfc73c0..cf023f5547 100644 --- a/src/main.h +++ b/src/main.h @@ -36,9 +36,16 @@ gboolean main_is_realized(void); #ifdef GEANY_PRIVATE +typedef enum NewInstanceMode +{ + NEW_INSTANCE_EXPLICITLY_DISABLED, + NEW_INSTANCE_DISABLED, + NEW_INSTANCE_ENABLED +} NewInstanceMode; + typedef struct { - gint new_instance; + NewInstanceMode new_instance_mode; gchar *socket_filename; gboolean load_session; gint goto_line; diff --git a/src/socket.c b/src/socket.c index 213ed1189c..a8a198e386 100644 --- a/src/socket.c +++ b/src/socket.c @@ -129,7 +129,7 @@ static void send_open_command(gint sock, gint argc, gchar **argv) { gint i; - g_return_if_fail(argc > 1 || cl_options.new_instance == -1); + g_return_if_fail(argc > 1 || cl_options.new_instance_mode == NEW_INSTANCE_EXPLICITLY_DISABLED); geany_debug("using running instance of Geany"); if (argc > 1) @@ -328,7 +328,7 @@ gint socket_init(gint argc, gchar **argv) SetForegroundWindow(hwnd); #endif /* now we send the command line args */ - if (argc > 1 || cl_options.new_instance == -1) + if (argc > 1 || cl_options.new_instance_mode == NEW_INSTANCE_EXPLICITLY_DISABLED) { send_open_command(sock, argc, argv); } diff --git a/src/ui_utils.c b/src/ui_utils.c index bbe87cad62..d65eecab1c 100644 --- a/src/ui_utils.c +++ b/src/ui_utils.c @@ -403,7 +403,7 @@ void ui_set_window_title(GeanyDocument *doc) g_string_append(str, "] - "); } g_string_append(str, "Geany"); - if (cl_options.new_instance == 1) + if (cl_options.new_instance_mode == NEW_INSTANCE_ENABLED) { g_string_append(str, _(" (new instance)")); }