Fix not grabbing keyboard, and add pid file to ensure one instance.

This commit is contained in:
QC 2015-01-31 18:23:17 +01:00
parent 983fff61b4
commit b74e6b791a
5 changed files with 103 additions and 3 deletions

View file

@ -39,6 +39,7 @@ rofi - A window switcher, run dialog and dmenu replacement
[ -eh *element height* ]
[ -lazy-filter-limit *limit* ]
[ -e *message*]
[ -pid *path* ]
[ -now ]
[ -rnow ]
[ -snow ]
@ -419,6 +420,13 @@ The default key combinations are:
Popup a message dialog (used internally for showing errors) with *message*.
Message can be multi-line.
### Other
'-pid' *path*
Make **rofi** create a pid file and check this on startup. Avoiding multiple copies running
simultaneous. This is useful when running rofi from a keybinding daemon.
### Debug
`-dump-xresources`

View file

@ -37,6 +37,7 @@ rofi \- A window switcher, run dialog and dmenu replacement
[ \-eh \fIelement height\fP ]
[ \-lazy\-filter\-limit \fIlimit\fP ]
[ \-e \fImessage\fP]
[ \-pid \fIpath\fP ]
[ \-now ]
[ \-rnow ]
[ \-snow ]
@ -516,6 +517,16 @@ Popup a message dialog (used internally for showing errors) with *message*.
Message can be multi\-line.
.fi
.RE
.SS Other
.PP
\&'\-pid' \fIpath\fP
.PP
.RS
.nf
Make **rofi** create a pid file and check this on startup. Avoiding multiple copies running
simultaneous. This is useful when running rofi from a keybinding daemon.
.fi
.RE
.SS Debug
.PP
\fB\fC\-dump\-xresources\fR
@ -652,10 +663,10 @@ Check quotes used on the commandline: e.g. used “ instead of ".
.UE
.SH AUTHOR
.PP
Qball Cow
Qball Cow
.MT qball@gmpclient.org
.ME
.PP
Original code based on work by: Sean Pringle
Original code based on work by: Sean Pringle
.MT sean.pringle@gmail.com
.ME

View file

@ -89,6 +89,18 @@ int find_arg_int ( const int argc, char * const argv[], const char * const key,
* @returns TRUE if key was found and val was set.
*/
int find_arg_str ( const int argc, char * const argv[], const char * const key, char** val );
/**
* @param argc Number of arguments.
* @param argv 2 dimensional array of arguments.
* @param key The key to search for
* @param val Pointer to the string to set to the key value (if found)
*
* Parse command line argument 'key' to string.
* Creates an allocated copy of the string.
*
* @returns TRUE if key was found and val was set.
*/
int find_arg_str_alloc ( const int argc, char * const argv[], const char * const key, char** val );
/**
* @param argc Number of arguments.

View file

@ -185,6 +185,16 @@ int find_arg_str ( const int argc, char * const argv[], const char * const key,
}
return FALSE;
}
int find_arg_str_alloc ( const int argc, char * const argv[], const char * const key, char** val )
{
int i = find_arg ( argc, argv, key );
if ( val != NULL && i > 0 && i < argc - 1 ) {
*val = g_strdup ( argv[i + 1] );
return TRUE;
}
return FALSE;
}
int find_arg_int ( const int argc, char * const argv[], const char * const key, int *val )
{

View file

@ -46,6 +46,7 @@
#include <X11/extensions/Xinerama.h>
#include <sys/wait.h>
#include <sys/file.h>
#ifdef HAVE_I3_IPC_H
#include <sys/types.h>
@ -74,6 +75,8 @@ int config_i3_mode = 0;
char *i3_socket_path = NULL;
#endif
char *pidfile = NULL;
const char *cache_dir = NULL;
unsigned int NumlockMask = 0;
Display *display = NULL;
@ -1800,7 +1803,8 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom
menu_refilter ( &state, lines, mmc, mmc_data, sorting, config.case_sensitive );
menu_update ( &state );
}
// Return like normal.
}
if ( mle == ML_TIMEOUT ) {
continue;
}
// Get next event. (might block)
@ -2453,6 +2457,8 @@ static void parse_cmd_options ( int argc, char ** argv )
exit ( EXIT_SUCCESS );
}
find_arg_str_alloc ( argc, argv, "-pid", &( pidfile ) );
find_arg_str ( argc, argv, "-switchers", &( config.switchers ) );
// Parse commandline arguments about the looks.
find_arg_uint ( argc, argv, "-opacity", &( config.window_opacity ) );
@ -2560,6 +2566,12 @@ static void cleanup ()
}
}
g_free ( switchers );
// Cleanup pid file.
if ( pidfile ) {
unlink ( pidfile );
g_free ( pidfile );
}
}
/**
@ -2701,7 +2713,42 @@ static void hup_action_handler ( int num )
XCloseDisplay ( display );
}
}
/**
* @param pidfile The pidfile to create.
*/
static void create_pid_file ( const char *pidfile )
{
if ( pidfile == NULL ) {
return;
}
int fd = open ( pidfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR );
if ( fd < 0 ) {
fprintf ( stderr, "Failed to create pid file." );
exit ( 1 );
}
// Set it to close the File Descriptor on exit.
int flags = fcntl ( fd, F_GETFD, NULL );
flags = flags | FD_CLOEXEC;
if ( fcntl ( fd, F_SETFD, flags, NULL ) < 0 ) {
fprintf ( stderr, "Failed to set CLOEXEC on pidfile." );
close ( fd );
exit ( 1 );
}
// Try to get exclusive write lock on FD
int retv = flock ( fd, LOCK_EX | LOCK_NB );
if ( retv != 0 ) {
fprintf ( stderr, "Failed to set lock on pidfile: Rofi already running?\n" );
fprintf ( stderr, "%d %s\n", retv, strerror ( errno ) );
exit ( 1 );
}
ftruncate ( fd, (off_t) 0 );
// Write pid.
char buffer[64];
int length = snprintf ( buffer, 64, "%i", getpid () );
write ( fd, buffer, length );
}
int main ( int argc, char *argv[] )
{
@ -2711,6 +2758,12 @@ int main ( int argc, char *argv[] )
// Get the path to the cache dir.
cache_dir = g_get_user_cache_dir ();
// Create pid file path.
const char *path = g_get_user_runtime_dir ();
if ( path ) {
pidfile = g_build_filename ( path, "rofi.pid", NULL );
}
// Register cleanup function.
atexit ( cleanup );
@ -2723,6 +2776,7 @@ int main ( int argc, char *argv[] )
return EXIT_FAILURE;
}
load_configuration ( display );
// Dump.
@ -2731,6 +2785,11 @@ int main ( int argc, char *argv[] )
exit ( EXIT_SUCCESS );
}
// Create pid file
if ( pidfile != NULL ) {
create_pid_file ( pidfile );
}
// setup_switchers
setup_switchers ();