diff --git a/doc/rofi.1 b/doc/rofi.1 index 9e8e4685..112cae8d 100644 --- a/doc/rofi.1 +++ b/doc/rofi.1 @@ -1017,6 +1017,12 @@ Command to open a Desktop Entry that is a Link. .PP Make \fBrofi\fP create a pid file and check this on startup. The pid file prevents multiple \fBrofi\fP instances from running simultaneously. This is useful when running \fBrofi\fP from a key\-binding daemon. +.PP +\fB\fC\-replace\fR + +.PP +If rofi is already running, based on pid file, try to kill that instance. + .PP \fB\fC\-display\-{mode}\fR \fIstring\fP diff --git a/doc/rofi.1.markdown b/doc/rofi.1.markdown index 0f85b7ae..8eccc414 100644 --- a/doc/rofi.1.markdown +++ b/doc/rofi.1.markdown @@ -617,6 +617,10 @@ Command to open a Desktop Entry that is a Link. Make **rofi** create a pid file and check this on startup. The pid file prevents multiple **rofi** instances from running simultaneously. This is useful when running **rofi** from a key-binding daemon. +`-replace` + +If rofi is already running, based on pid file, try to kill that instance. + `-display-{mode}` *string* Set the name to use for mode. This is used as prompt and in combi-browser. diff --git a/include/helper.h b/include/helper.h index 7ae37a65..12ed0f70 100644 --- a/include/helper.h +++ b/include/helper.h @@ -149,10 +149,11 @@ int execute_generator(const char *cmd) __attribute__((nonnull)); /** * @param pidfile The pidfile to create. + * @param kill Try killing running instance. * * returns file descriptor (or -1 when failed) */ -int create_pid_file(const char *pidfile); +int create_pid_file(const char *pidfile, gboolean kill); /** * Remove pid file diff --git a/source/helper.c b/source/helper.c index e9bf3a76..a8b98979 100644 --- a/source/helper.c +++ b/source/helper.c @@ -536,7 +536,7 @@ int execute_generator(const char *cmd) { return fd; } -int create_pid_file(const char *pidfile) { +int create_pid_file(const char *pidfile, gboolean kill_running) { if (pidfile == NULL) { return -1; } @@ -559,6 +559,26 @@ int create_pid_file(const char *pidfile) { if (retv != 0) { g_warning("Failed to set lock on pidfile: Rofi already running?"); g_warning("Got error: %d %s", retv, g_strerror(errno)); + if (kill_running) { + char buffer[64] = { + 0, + }; + ssize_t l = read(fd, &buffer, 64); + if (l > 1) { + pid_t pid = g_ascii_strtoll(buffer, NULL, 0); + kill(pid, SIGTERM); + while (1) { + retv = flock(fd, LOCK_EX | LOCK_NB); + if (retv == 0) { + break; + } + g_usleep(100); + } + } + remove_pid_file(fd); + return create_pid_file(pidfile, FALSE); + } + remove_pid_file(fd); return -1; } @@ -1263,10 +1283,10 @@ char *helper_string_replace_if_exists(char *string, ...) { * @param h Hash table with set of {key}, value that will be replaced, * terminated by a NULL * - * Items {key} are replaced by the value if '{key}' is passed as key/value pair, - * otherwise removed from string. If the {key} is in between [] all the text - * between [] are removed if {key} is not found. Otherwise key is replaced and [ - * & ] removed. + * Items {key} are replaced by the value if '{key}' is passed as key/value + * pair, otherwise removed from string. If the {key} is in between [] all the + * text between [] are removed if {key} is not found. Otherwise key is + * replaced and [ & ] removed. * * This allows for optional replacement, f.e. '{ssh-client} [-t {title}] -e * "{cmd}"' the '-t {title}' is only there if {title} is set. diff --git a/source/rofi.c b/source/rofi.c index 2ccf549c..6bc0272c 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -1047,8 +1047,12 @@ int main(int argc, char *argv[]) { rofi_icon_fetcher_init(); TICK_N("Icon fetcher initialize"); + gboolean kill_running = FALSE; + if (find_arg("-replace") >= 0) { + kill_running = TRUE; + } // Create pid file - int pfd = create_pid_file(pidfile); + int pfd = create_pid_file(pidfile, kill_running); TICK_N("Pid file created"); if (pfd < 0) { cleanup(); diff --git a/source/xrmoptions.c b/source/xrmoptions.c index 9700f18e..bb04fb53 100644 --- a/source/xrmoptions.c +++ b/source/xrmoptions.c @@ -701,7 +701,7 @@ gboolean config_parse_set_property(const Property *p, char **error) { } } //*error = g_strdup_printf("Option: %s is not found.", p->name); - g_warning("Option: %s is not found.", p->name); + g_debug("Option: %s is not found.", p->name); for (GList *iter = g_list_first(extra_parsed_options); iter != NULL; iter = g_list_next(iter)) { diff --git a/test/helper-pidfile.c b/test/helper-pidfile.c index fabb6c4c..090d7002 100644 --- a/test/helper-pidfile.c +++ b/test/helper-pidfile.c @@ -25,104 +25,81 @@ * */ -#include -#include -#include -#include -#include -#include -#include #include "display.h" -#include "xcb.h" -#include "xcb-internal.h" +#include "rofi-icon-fetcher.h" #include "rofi.h" #include "settings.h" #include "widgets/textbox.h" -#include "rofi-icon-fetcher.h" +#include "xcb-internal.h" +#include "xcb.h" +#include +#include +#include +#include +#include +#include +#include -static int test = 0; +static int test = 0; -#define TASSERT( a ) { \ - assert ( a ); \ - printf ( "Test %i passed (%s)\n", ++test, # a ); \ -} +#define TASSERT(a) \ + { \ + assert(a); \ + printf("Test %i passed (%s)\n", ++test, #a); \ + } #include "theme.h" ThemeWidget *rofi_theme = NULL; -uint32_t rofi_icon_fetcher_query ( const char *name, const int size ) -{ - return 0; -} -uint32_t rofi_icon_fetcher_query_advanced ( const char *name, const int wsize, const int hsize ) -{ +uint32_t rofi_icon_fetcher_query(const char *name, const int size) { return 0; } +uint32_t rofi_icon_fetcher_query_advanced(const char *name, const int wsize, + const int hsize) { return 0; } -cairo_surface_t * rofi_icon_fetcher_get ( const uint32_t uid ) -{ - return NULL; -} +cairo_surface_t *rofi_icon_fetcher_get(const uint32_t uid) { return NULL; } -void rofi_clear_error_messages ( void ) -{ -} +void rofi_clear_error_messages(void) {} -gboolean rofi_theme_parse_string ( const char *string ) -{ - return FALSE; +gboolean rofi_theme_parse_string(const char *string) { return FALSE; } +double textbox_get_estimated_char_height(void) { return 12.0; } +void rofi_view_get_current_monitor(int *width, int *height) { + *width = 1920; + *height = 1080; } -double textbox_get_estimated_char_height ( void ) -{ - return 12.0; -} -void rofi_view_get_current_monitor ( int *width, int *height ) -{ -*width = 1920; -*height = 1080; -} -double textbox_get_estimated_ch ( void ) -{ - return 9.0; -} -void rofi_add_error_message ( G_GNUC_UNUSED GString *msg ) -{ -} -int rofi_view_error_dialog ( const char *msg, G_GNUC_UNUSED int markup ) -{ - fputs ( msg, stderr ); - return TRUE; -} -int monitor_active ( G_GNUC_UNUSED workarea *mon ) -{ - return 0; +double textbox_get_estimated_ch(void) { return 9.0; } +void rofi_add_error_message(G_GNUC_UNUSED GString *msg) {} +int rofi_view_error_dialog(const char *msg, G_GNUC_UNUSED int markup) { + fputs(msg, stderr); + return TRUE; } +int monitor_active(G_GNUC_UNUSED workarea *mon) { return 0; } -void display_startup_notification ( G_GNUC_UNUSED RofiHelperExecuteContext *context, G_GNUC_UNUSED GSpawnChildSetupFunc *child_setup, G_GNUC_UNUSED gpointer *user_data ) -{ -} +void display_startup_notification( + G_GNUC_UNUSED RofiHelperExecuteContext *context, + G_GNUC_UNUSED GSpawnChildSetupFunc *child_setup, + G_GNUC_UNUSED gpointer *user_data) {} -int main ( G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv ) -{ - if ( setlocale ( LC_ALL, "" ) == NULL ) { - fprintf ( stderr, "Failed to set locale.\n" ); - return EXIT_FAILURE; - } - // Pid test. - // Tests basic functionality of writing it, locking, seeing if I can write same again - // And close/reopen it again. - { - const char *tmpd = g_get_tmp_dir (); - char *path = g_build_filename (tmpd, "rofi-pid.pid", NULL); - TASSERT ( create_pid_file ( NULL ) == -1 ); - int fd = create_pid_file ( path ); - TASSERT ( fd >= 0 ); - int fd2 = create_pid_file ( path ); - TASSERT ( fd2 < 0 ); +int main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv) { + if (setlocale(LC_ALL, "") == NULL) { + fprintf(stderr, "Failed to set locale.\n"); + return EXIT_FAILURE; + } + // Pid test. + // Tests basic functionality of writing it, locking, seeing if I can write + // same again And close/reopen it again. + { + const char *tmpd = g_get_tmp_dir(); + char *path = g_build_filename(tmpd, "rofi-pid.pid", NULL); + TASSERT(create_pid_file(NULL, FALSE) == -1); + int fd = create_pid_file(path, FALSE); + TASSERT(fd >= 0); + int fd2 = create_pid_file(path, FALSE); + TASSERT(fd2 < 0); - remove_pid_file ( fd ); - fd = create_pid_file ( path ); - TASSERT ( fd >= 0 ); - remove_pid_file ( fd ); - free ( path ); - } + remove_pid_file(fd); + fd = create_pid_file(path, FALSE); + TASSERT(fd >= 0); + remove_pid_file(fd); + free(path); + } }