diff options
-rw-r--r-- | INSTALL.md | 29 | ||||
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | README.md | 16 | ||||
-rw-r--r-- | configure.ac | 10 | ||||
-rw-r--r-- | include/theme.h | 1 | ||||
-rw-r--r-- | include/xrmoptions.h | 33 | ||||
-rw-r--r-- | lexer/theme-lexer.l | 31 | ||||
-rw-r--r-- | lexer/theme-parser.y | 11 | ||||
-rw-r--r-- | source/dialogs/drun.c | 4 | ||||
-rw-r--r-- | source/mode.c | 3 | ||||
-rw-r--r-- | source/rofi.c | 123 | ||||
-rw-r--r-- | source/theme.c | 2 | ||||
-rw-r--r-- | source/view.c | 4 | ||||
-rw-r--r-- | source/x11-helper.c | 1 | ||||
-rw-r--r-- | source/xrmoptions.c | 110 | ||||
-rw-r--r-- | test/box-test.c | 3 | ||||
-rw-r--r-- | test/scrollbar-test.c | 3 | ||||
-rw-r--r-- | test/textbox-test.c | 4 | ||||
-rw-r--r-- | test/widget-test.c | 3 |
19 files changed, 244 insertions, 151 deletions
@@ -1,5 +1,10 @@ # Installation guide +This guide explains how to install rofi using its build system and how you can make debug builds. + +Rofi uses autotools (GNU Build system), for more information see +[here](https://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html). + ## DEPENDENCY ### For building: @@ -20,6 +25,8 @@ * libcairo * libcairo-xcb * libglib2.0 >= 2.40 + * gmodule-2.0 + * gio-unix-2.0 * libstartup-notification-1.0 * libxkbcommon >= 0.5.0 * libxkbcommon-x11 @@ -51,6 +58,7 @@ The actual install, execute as root (if needed): make install ``` +The default installation prefix is: `/usr/local/` use `./configure --prefix={prefix}` to install into another location. ## Install a checkout from git @@ -59,6 +67,14 @@ The GitHub Pages version of these directions may be out of date. Please use [master-install]: https://github.com/DaveDavenport/rofi/blob/master/INSTALL.md#install-a-checkout-from-git +Make a checkout: + +``` +git clone https://github.com/DaveDavenport/rofi +cd rofi/ +``` + + Pull in dependencies ``` @@ -142,7 +158,7 @@ make V=1 ### Debug build -Compile with debug symbols and no optimization +Compile with debug symbols and no optimization, this is useful for making backtraces: ``` make CFLAGS="-O0 -g3" clean rofi @@ -159,12 +175,15 @@ can then load the core in GDB. gdb rofi core ``` +> Where the core file is located and what its exact name is different on each distributions. Please consult the +> relevant documentation. + ## Install distribution ### Debian or Ubuntu ``` -apt-get install rofi +apt install rofi ``` @@ -174,3 +193,9 @@ rofi from [russianfedora repository](http://ru.fedoracommunity.org/repository) and also [Yaroslav's COPR (Cool Other Package Repo)](https://copr.fedorainfracloud.org/coprs/yaroslav/i3desktop/) + +### ArchLinux + +``` +pacman -S rofi +``` diff --git a/Makefile.am b/Makefile.am index 41fff9e1..5eb96e3f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,6 +20,10 @@ BUILT_SOURCES=\ lexer/theme-parser.c\ lexer/theme-lexer.c +$(top_builddir)/lexer/theme-lexer.c: $(top_srcdir)/lexer/theme-lexer.l + +$(top_builddir)/lexer/theme-parser.c $(top_builddir)/lexer/theme-parser.h: $(top_srcdir)/lexer/theme-parser.y + rofiincludedir=${includedir}/rofi rofiinclude_HEADERS=\ include/mode.h\ @@ -7,13 +7,13 @@ [![Coverity](https://scan.coverity.com/projects/3850/badge.svg)](https://scan.coverity.com/projects/davedavenport-rofi) [![Forum](https://img.shields.io/badge/forum-online-green.svg)](https://forum.qtools.org) -# A window switcher, run dialog and dmenu replacement +# A window switcher, Application launcher and dmenu replacement **Rofi** started as clone of simpleswitcher, written by [Sean Pringle](http://github.com/seanpringle/simpleswitcher) a popup window switcher roughly based on [superswitcher](http://code.google.com/p/superswitcher/). Simpleswitcher laid the foundations and therefor Sean Pringle deserves most of the credit for this tool. **Rofi**, -renamed as it lost the *simple* property, has been extended with extra features, like a run-dialog, ssh-launcher and -can act as a drop-in dmenu replacement, making it a very versatile tool. +renamed as it lost the *simple* property, has been extended with extra features, like a application launcher, +ssh-launcher and can act as a drop-in dmenu replacement, making it a very versatile tool. **Rofi**, like dmenu, will provide the user with a textual list of options where one or more can be selected. This can either be, running an application, selecting a window or options provided by an external script. @@ -33,8 +33,8 @@ It main features are: * Build in modes: - Window switcher mode. - EWMH compatible WM. - - Run mode. - - Desktop File Run mode. + - Application launcher. + - Desktop File Application launcher. - SSH launcher mode. - Combi mode, allow several modes to be merged into one list. * History based ordering last 25 choices are ordered on top based on use. (optional) @@ -65,7 +65,7 @@ Window mode features: - Custom command by `Shift-Return` -## Run mode +## Application launcher ![run mode](https://davedavenport.github.io/rofi/images/rofi/run-dialog.png) @@ -78,7 +78,7 @@ Run mode features: - Execute command to add custom entries, like aliases. -## DRun mode +## Desktop File Application launcher The desktop run mode allows users to quickly search and launch an application from the *freedesktop.org* Desktop Entries. These are used by most common Desktop Environments to populate launchers and menus. @@ -240,7 +240,7 @@ The boolean option has a non-default commandline syntax, to enable option X you to disable it: rofi -no-X - + # Manpage For more detailed information, please see the [manpage](doc/rofi-manpage.markdown), the [wiki](https://github.com/DaveDavenport/rofi/wiki) or the [forum](https://forum.qtools.org). diff --git a/configure.ac b/configure.ac index 7d982ef2..1b027d2e 100644 --- a/configure.ac +++ b/configure.ac @@ -141,6 +141,16 @@ echo "Window Switcher dialog Enabled" else echo "Window Switcher dialog Disabled" fi +if test x$enable_asan = xyes; then +echo "Asan address sanitize Enabled" +else +echo "Asan address sanitize Disabled" +fi +if test x$enable_gcov = xyes; then +echo "Code Coverage Enabled" +else +echo "Code Coverage Disabled" +fi echo "-------------------------------------" echo "Now type 'make' to build" echo "" diff --git a/include/theme.h b/include/theme.h index 6030b0e0..aece11ae 100644 --- a/include/theme.h +++ b/include/theme.h @@ -4,6 +4,7 @@ #include <cairo.h> #include <widgets/widget.h> #include <settings.h> +#include "theme.h" /** Style of text highlight */ typedef enum diff --git a/include/xrmoptions.h b/include/xrmoptions.h index b4abc76b..99bec516 100644 --- a/include/xrmoptions.h +++ b/include/xrmoptions.h @@ -1,6 +1,7 @@ #ifndef ROFI_XRMOPTIONS_H #define ROFI_XRMOPTIONS_H #include "xcb.h" +#include "theme.h" // Big thanks to Sean Pringle for this code. /** @@ -77,30 +78,6 @@ void config_parse_xresource_options_file ( const char *filename ); void config_parse_cmd_options ( void ); /** - * Parse dynamic commandline options. - * @ingroup CONFCommandline - */ -void config_parse_cmd_options_dynamic ( void ); - -/** - * @param xcb Handler object that holds connection to X11 server to fetch the settings from. - * - * Parse the rofi related X resource options of the - * connected X server. - * - * @ingroup CONFXServer - */ -void config_parse_xresource_options_dynamic ( xcb_stuff *xcb ); - -/** - * @param filename The xresources file to parse - * - * Parses filename and updates the config. For dynamic options. - * @ingroup CONFFile - */ -void config_parse_xresource_options_dynamic_file ( const char *filename ); - -/** * Free any allocated memory. * * @ingroup CONFXResources @@ -158,5 +135,13 @@ void print_help_msg ( const char *option, const char *type, const char*text, con */ char ** config_parser_return_display_help ( unsigned int *length ); +/** + * @brief Set config option. + * + * Sets both the static as dynamic config option. + * + * @param p Property to set + */ +void config_parse_set_property ( const Property *p ); /* @}*/ #endif diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index b2c2914a..5c62e2b5 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -1,4 +1,6 @@ -%option noyywrap nounput never-interactive +%option noyywrap +%option nounput +%option never-interactive %option bison-locations %{ @@ -35,7 +37,7 @@ typedef struct _ParseObject { char *filename; /** Length of string */ - size_t str_len; + yy_size_t str_len; /** String */ const char *input_str; /** Position in file */ @@ -100,9 +102,21 @@ static char * rofi_theme_parse_prepare_file ( const char *file, const char *pare yylloc->first_column = yylloc->last_column;\ } %} + +ASC [\x00-\x7f] +ASCN [\x00-\t\v-\x7f] +U [\x80-\xbf] +U2 [\xc2-\xdf] +U3 [\xe0-\xef] +U4 [\xf0-\xf4] + + // UANY {ASC}|{U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} +UANYN {ASCN}|{U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} + // UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} + WHITESPACE [[:blank:]] WORD [[:alnum:]-]+ -STRING [[:print:]]+ +STRING {UANYN}+ HEX [[:xdigit:]] NUMBER [[:digit:]] PNNUMBER [-+]?[[:digit:]]+ @@ -129,6 +143,8 @@ LS_SOLID "solid" INCLUDE "@import" +CONFIGURATION "Configuration" + %x INCLUDE %x PROPERTIES %x NAMESTR @@ -143,6 +159,9 @@ YY_LLOC_START if ( queue == NULL ){ queue = g_queue_new ( ); yylloc->filename = current->filename; + // unsure why todo this. + yylloc->first_line = yylloc->last_line = 1; + yylloc->first_column = yylloc->last_column = 1; } %} @@ -245,6 +264,12 @@ if ( queue == NULL ){ /** * Handle defaults: * { ... } */ +<INITIAL>{CONFIGURATION} { + g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); + BEGIN(DEFAULTS); + return CONFIGURATION; + +} <INITIAL>{ASTERIX} { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(DEFAULTS); diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y index e304ff29..4a5368b8 100644 --- a/lexer/theme-parser.y +++ b/lexer/theme-parser.y @@ -7,6 +7,7 @@ %parse-param {const char *what} %code requires { #include "theme.h" +#include "xrmoptions.h" typedef struct YYLTYPE { int first_line; @@ -89,6 +90,7 @@ int yylex (YYSTYPE *, YYLTYPE *); %token NAME_PREFIX "Element section ('# {name} { ... }')" %token WHITESPACE "White space" %token PDEFAULTS "Default settings section ( '* { ... }')" +%token CONFIGURATION "Configuration block" %type <ival> highlight_styles %type <sval> entry @@ -131,6 +133,15 @@ NAME_PREFIX name_path BOPEN optional_properties BCLOSE PDEFAULTS BOPEN optional_properties BCLOSE { rofi_theme_widget_add_properties ( rofi_theme, $3); } +| CONFIGURATION BOPEN optional_properties BCLOSE { + GHashTableIter iter; + g_hash_table_iter_init ( &iter, $3 ); + gpointer key,value; + while ( g_hash_table_iter_next ( &iter, &key, &value ) ) { + Property *p = (Property *) value; + config_parse_set_property ( p ); + } +} ; /** diff --git a/source/dialogs/drun.c b/source/dialogs/drun.c index 844bb7ef..1eab9d19 100644 --- a/source/dialogs/drun.c +++ b/source/dialogs/drun.c @@ -371,8 +371,8 @@ static void get_apps_history ( DRunModePrivateData *pd ) for ( unsigned int index = 0; index < length; index++ ) { char **st = g_strsplit ( retv[index], ":::", 2 ); if ( st && st[0] && st[1] ) { - if ( ! read_desktop_file ( pd, st[0], st[1] ) ) { - history_remove ( path, retv[index]); + if ( !read_desktop_file ( pd, st[0], st[1] ) ) { + history_remove ( path, retv[index] ); } } g_strfreev ( st ); diff --git a/source/mode.c b/source/mode.c index c3a1456f..e3e24a6d 100644 --- a/source/mode.c +++ b/source/mode.c @@ -17,8 +17,7 @@ int mode_init ( Mode *mode ) { g_return_val_if_fail ( mode != NULL, FALSE ); g_return_val_if_fail ( mode->_init != NULL, FALSE ); - mode->_init ( mode ); - return TRUE; + return mode->_init ( mode ); } void mode_destroy ( Mode *mode ) diff --git a/source/rofi.c b/source/rofi.c index 56a03608..f67b337f 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -73,7 +73,7 @@ // TODO: move this check to mode.c #include "mode-private.h" -#define LOG_DOMAIN "Rofi" +#define LOG_DOMAIN "Rofi" // Pidfile. char *pidfile = NULL; @@ -172,7 +172,7 @@ static int setup () */ static void teardown ( int pfd ) { - g_log ( LOG_DOMAIN , G_LOG_LEVEL_DEBUG, "Teardown"); + g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Teardown" ); // Cleanup font setup. textbox_cleanup ( ); @@ -333,7 +333,6 @@ static void help ( G_GNUC_UNUSED int argc, char **argv ) } /** - * Function bound by 'atexit'. * Cleanup globally allocated memory. */ static void cleanup () @@ -543,7 +542,6 @@ static int add_mode ( const char * token ) Mode *sw = script_switcher_parse_setup ( token ); if ( sw != NULL ) { modi[num_modi] = sw; - mode_set_config ( sw ); num_modi++; } else { @@ -565,36 +563,6 @@ static void setup_modi ( void ) } // Free string that was modified by strtok_r g_free ( switcher_str ); - rofi_collect_modi_setup (); -} - -/** - * Load configuration. - * Following priority: (current), X, commandline arguments - */ -static inline void load_configuration ( ) -{ - // Load distro default settings - gchar *etc = g_build_filename ( SYSCONFDIR, "rofi.conf", NULL ); - if ( g_file_test ( etc, G_FILE_TEST_IS_REGULAR ) ) { - config_parse_xresource_options_file ( etc ); - } - g_free ( etc ); - // Load in config from X resources. - config_parse_xresource_options ( xcb ); - config_parse_xresource_options_file ( config_path ); -} -static inline void load_configuration_dynamic ( ) -{ - // Load distro default settings - gchar *etc = g_build_filename ( SYSCONFDIR, "rofi.conf", NULL ); - if ( g_file_test ( etc, G_FILE_TEST_IS_REGULAR ) ) { - config_parse_xresource_options_dynamic_file ( etc ); - } - g_free ( etc ); - // Load in config from X resources. - config_parse_xresource_options_dynamic ( xcb ); - config_parse_xresource_options_dynamic_file ( config_path ); } /** @@ -866,7 +834,7 @@ int main ( int argc, char *argv[] ) #else fprintf ( stdout, "Version: "VERSION "\n" ); #endif - exit ( EXIT_SUCCESS ); + return EXIT_SUCCESS; } // Detect if we are in dmenu mode. @@ -897,10 +865,12 @@ int main ( int argc, char *argv[] ) const char *path = g_get_user_runtime_dir (); if ( path ) { if ( g_mkdir_with_parents ( path, 0700 ) < 0 ) { - fprintf ( stderr, "Failed to create user runtime directory: %s\n", strerror ( errno ) ); - return EXIT_FAILURE; + g_log ( LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Failed to create user runtime directory: %s with error: %s\n", path, strerror ( errno ) ); + pidfile = g_build_filename ( g_get_home_dir (), ".rofi.pid", NULL ); + } + else { + pidfile = g_build_filename ( path, "rofi.pid", NULL ); } - pidfile = g_build_filename ( path, "rofi.pid", NULL ); } config_parser_add_option ( xrm_String, "pid", (void * *) &pidfile, "Pidfile location" ); @@ -917,12 +887,9 @@ int main ( int argc, char *argv[] ) } TICK (); - // Register cleanup function. - atexit ( cleanup ); - - TICK (); if ( setlocale ( LC_ALL, "" ) == NULL ) { fprintf ( stderr, "Failed to set locale.\n" ); + cleanup (); return EXIT_FAILURE; } @@ -934,11 +901,13 @@ int main ( int argc, char *argv[] ) xcb->connection = xcb_connect ( display_str, &xcb->screen_nbr ); if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Failed to open display: %s", display_str ); + cleanup (); return EXIT_FAILURE; } TICK_N ( "Open Display" ); rofi_collect_modi (); + rofi_collect_modi_setup (); TICK_N ( "Collect MODI" ); xcb->screen = xcb_aux_get_screen ( xcb->connection, xcb->screen_nbr ); @@ -959,12 +928,14 @@ int main ( int argc, char *argv[] ) if ( xkb_x11_setup_xkb_extension ( xcb->connection, XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION, XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS, NULL, NULL, &xkb.first_event, NULL ) < 0 ) { fprintf ( stderr, "cannot setup XKB extension!\n" ); + cleanup (); return EXIT_FAILURE; } xkb.context = xkb_context_new ( XKB_CONTEXT_NO_FLAGS ); if ( xkb.context == NULL ) { fprintf ( stderr, "cannot create XKB context!\n" ); + cleanup (); return EXIT_FAILURE; } xkb.xcb_connection = xcb->connection; @@ -1015,11 +986,13 @@ int main ( int argc, char *argv[] ) xkb.keymap = xkb_x11_keymap_new_from_device ( xkb.context, xcb->connection, xkb.device_id, XKB_KEYMAP_COMPILE_NO_FLAGS ); if ( xkb.keymap == NULL ) { fprintf ( stderr, "Failed to get Keymap for current keyboard device.\n" ); + cleanup (); return EXIT_FAILURE; } xkb.state = xkb_x11_state_new_from_device ( xkb.keymap, xcb->connection, xkb.device_id ); if ( xkb.state == NULL ) { fprintf ( stderr, "Failed to get state object for current keyboard device.\n" ); + cleanup (); return EXIT_FAILURE; } @@ -1033,13 +1006,15 @@ int main ( int argc, char *argv[] ) if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Connection has error\n" ); - exit ( EXIT_FAILURE ); + cleanup (); + return EXIT_FAILURE; } x11_setup ( &xkb ); TICK_N ( "Setup xkb" ); if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Connection has error\n" ); - exit ( EXIT_FAILURE ); + cleanup (); + return EXIT_FAILURE; } main_loop = g_main_loop_new ( NULL, FALSE ); @@ -1048,7 +1023,8 @@ int main ( int argc, char *argv[] ) xcb->sndisplay = sn_xcb_display_new ( xcb->connection, error_trap_push, error_trap_pop ); if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Connection has error\n" ); - exit ( EXIT_FAILURE ); + cleanup (); + return EXIT_FAILURE; } if ( xcb->sndisplay != NULL ) { @@ -1056,7 +1032,8 @@ int main ( int argc, char *argv[] ) } if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Connection has error\n" ); - exit ( EXIT_FAILURE ); + cleanup (); + return EXIT_FAILURE; } TICK_N ( "Startup Notification" ); // Setup keybinding @@ -1064,10 +1041,30 @@ int main ( int argc, char *argv[] ) TICK_N ( "Setup abe" ); if ( find_arg ( "-no-config" ) < 0 ) { - load_configuration ( ); + // Load distro default settings + gchar *etc = g_build_filename ( SYSCONFDIR, "rofi.conf", NULL ); + if ( g_file_test ( etc, G_FILE_TEST_IS_REGULAR ) ) { + config_parse_xresource_options_file ( etc ); + } + g_free ( etc ); + // Load in config from X resources. + config_parse_xresource_options ( xcb ); + config_parse_xresource_options_file ( config_path ); + + find_arg_str ( "-theme", &( config.theme ) ); + if ( config.theme ) { + TICK_N ( "Parse theme" ); + if ( rofi_theme_parse_file ( config.theme ) ) { + // TODO: instantiate fallback theme.? + rofi_theme_free ( rofi_theme ); + rofi_theme = NULL; + } + TICK_N ( "Parsed theme" ); + } } // Parse command line for settings, independent of other -no-config. config_parse_cmd_options ( ); + TICK_N ( "Load cmd config " ); if ( !dmenu_mode ) { // setup_modi @@ -1075,25 +1072,6 @@ int main ( int argc, char *argv[] ) TICK_N ( "Setup Modi" ); } - if ( find_arg ( "-no-config" ) < 0 ) { - // Reload for dynamic part. - load_configuration_dynamic ( ); - TICK_N ( "Load config dynamic" ); - } - // Parse command line for settings, independent of other -no-config. - config_parse_cmd_options_dynamic ( ); - TICK_N ( "Load cmd config dynamic" ); - - if ( config.theme ) { - TICK_N ( "Parse theme" ); - if ( rofi_theme_parse_file ( config.theme ) ) { - // TODO: instantiate fallback theme.? - rofi_theme_free ( rofi_theme ); - rofi_theme = NULL; - } - TICK_N ( "Parsed theme" ); - } - const char ** theme_str = find_arg_strv ( "-theme-str" ); if ( theme_str ) { for ( int index = 0; theme_str && theme_str[index]; index++ ) { @@ -1110,21 +1088,25 @@ int main ( int argc, char *argv[] ) if ( find_arg ( "-dump-theme" ) >= 0 ) { rofi_theme_print ( rofi_theme ); - exit ( EXIT_SUCCESS ); + cleanup (); + return EXIT_SUCCESS; } // Dump. // catch help request if ( find_arg ( "-h" ) >= 0 || find_arg ( "-help" ) >= 0 || find_arg ( "--help" ) >= 0 ) { help ( argc, argv ); - exit ( EXIT_SUCCESS ); + cleanup (); + return EXIT_SUCCESS; } if ( find_arg ( "-dump-xresources" ) >= 0 ) { config_parse_xresource_dump (); - exit ( EXIT_SUCCESS ); + cleanup (); + return EXIT_SUCCESS; } if ( find_arg ( "-dump-xresources-theme" ) >= 0 ) { config_parse_xresources_theme_dump (); - exit ( EXIT_SUCCESS ); + cleanup (); + return EXIT_SUCCESS; } main_loop_source = g_water_xcb_source_new_for_connection ( NULL, xcb->connection, main_loop_x11_event_handler, NULL, NULL ); @@ -1147,5 +1129,6 @@ int main ( int argc, char *argv[] ) // Start mainloop. g_main_loop_run ( main_loop ); teardown ( pfd ); + cleanup (); return return_code; } diff --git a/source/theme.c b/source/theme.c index a99d85f2..ab660315 100644 --- a/source/theme.c +++ b/source/theme.c @@ -767,7 +767,7 @@ void rofi_theme_convert_old_theme ( void ) ThemeWidget *walternate = rofi_theme_find_or_create_name ( widget, "alternate" ); rofi_theme_convert_create_property_ht ( widget ); - Property *p= rofi_theme_property_create ( P_INTEGER ); + Property *p = rofi_theme_property_create ( P_INTEGER ); p->name = g_strdup ( "border" ); p->value.i = 0; g_hash_table_replace ( widget->properties, p->name, p ); diff --git a/source/view.c b/source/view.c index 9702de5b..5ea660e3 100644 --- a/source/view.c +++ b/source/view.c @@ -1739,7 +1739,7 @@ void rofi_view_cleanup () CacheState.edit_surf = NULL; } if ( CacheState.main_window != XCB_WINDOW_NONE ) { - g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Unmapping and free'ing window"); + g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Unmapping and free'ing window" ); xcb_unmap_window ( xcb->connection, CacheState.main_window ); xcb_free_gc ( xcb->connection, CacheState.gc ); xcb_free_pixmap ( xcb->connection, CacheState.edit_pixmap ); @@ -1783,7 +1783,7 @@ void rofi_view_workers_initialize ( void ) void rofi_view_workers_finalize ( void ) { if ( tpool ) { - g_thread_pool_free ( tpool, TRUE, FALSE ); + g_thread_pool_free ( tpool, TRUE, TRUE ); tpool = NULL; } } diff --git a/source/x11-helper.c b/source/x11-helper.c index 4b5dea57..67d3e74e 100644 --- a/source/x11-helper.c +++ b/source/x11-helper.c @@ -881,6 +881,7 @@ xcb_window_t xcb_stuff_get_root_window ( xcb_stuff *xcb ) void xcb_stuff_wipe ( xcb_stuff *xcb ) { if ( xcb->connection != NULL ) { + g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Cleaning up XCB and XKB" ); if ( xcb->sncontext != NULL ) { sn_launchee_context_unref ( xcb->sncontext ); xcb->sncontext = NULL; diff --git a/source/xrmoptions.c b/source/xrmoptions.c index 9c017377..04126acd 100644 --- a/source/xrmoptions.c +++ b/source/xrmoptions.c @@ -49,6 +49,7 @@ const char * const ConfigSourceStr[] = { "Default", "XResources", "File", + "Rasi File", "Commandline", }; /** Enumerator of different sources of configuration. */ @@ -57,7 +58,8 @@ enum ConfigSource CONFIG_DEFAULT = 0, CONFIG_XRESOURCES = 1, CONFIG_FILE = 2, - CONFIG_CMDLINE = 3 + CONFIG_FILE_THEME = 3, + CONFIG_CMDLINE = 4 }; typedef struct @@ -275,11 +277,31 @@ static void __config_parse_xresource_options ( xcb_xrm_database_t *xDB, enum Con g_free ( name ); } } +static void __config_parse_xresource_options_dynamic ( xcb_xrm_database_t *xDB, enum ConfigSource source ) +{ + const char * namePrefix = "rofi"; + + for ( unsigned int i = 0; i < num_extra_options; ++i ) { + char *name; + + name = g_strdup_printf ( "%s.%s", namePrefix, extra_options[i].name ); + char *xrmValue = NULL; + if ( xcb_xrm_resource_get_string ( xDB, name, NULL, &xrmValue ) == 0 ) { + config_parser_set ( &( extra_options[i] ), xrmValue, source ); + } + if ( xrmValue ) { + free ( xrmValue ); + } + + g_free ( name ); + } +} void config_parse_xresource_options ( xcb_stuff *xcb ) { xcb_xrm_database_t *xDB = xcb_xrm_database_from_default ( xcb->connection ); if ( xDB ) { __config_parse_xresource_options ( xDB, CONFIG_XRESOURCES ); + __config_parse_xresource_options_dynamic ( xDB, CONFIG_XRESOURCES ); xcb_xrm_database_free ( xDB ); } } @@ -294,6 +316,7 @@ void config_parse_xresource_options_file ( const char *filename ) return; } __config_parse_xresource_options ( xDB, CONFIG_FILE ); + __config_parse_xresource_options_dynamic ( xDB, CONFIG_FILE ); xcb_xrm_database_free ( xDB ); } @@ -356,58 +379,71 @@ void config_parse_cmd_options ( void ) XrmOption *op = &( xrmOptions[i] ); config_parse_cmd_option ( op ); } -} - -void config_parse_cmd_options_dynamic ( void ) -{ for ( unsigned int i = 0; i < num_extra_options; ++i ) { XrmOption *op = &( extra_options[i] ); config_parse_cmd_option ( op ); } } -static void __config_parse_xresource_options_dynamic ( xcb_xrm_database_t *xDB, enum ConfigSource source ) +static void __config_parser_set_property ( XrmOption *option, const Property *p ) { - const char * namePrefix = "rofi"; - - for ( unsigned int i = 0; i < num_extra_options; ++i ) { - char *name; - - name = g_strdup_printf ( "%s.%s", namePrefix, extra_options[i].name ); - char *xrmValue = NULL; - if ( xcb_xrm_resource_get_string ( xDB, name, NULL, &xrmValue ) == 0 ) { - config_parser_set ( &( extra_options[i] ), xrmValue, source ); + if ( option->type == xrm_String ) { + if ( p->type != P_STRING ) { + fprintf ( stderr, "Option: %s needs to be set with a string.\n", option->name ); + return; } - if ( xrmValue ) { - free ( xrmValue ); + if ( ( option )->mem != NULL ) { + g_free ( option->mem ); + option->mem = NULL; } + *( option->value.str ) = g_strdup ( p->value.s ); - g_free ( name ); + // Memory + ( option )->mem = *( option->value.str ); + option->source = CONFIG_FILE_THEME; } -} - -void config_parse_xresource_options_dynamic ( xcb_stuff *xcb ) -{ - char *name = window_get_text_prop ( xcb_stuff_get_root_window ( xcb ), XCB_ATOM_RESOURCE_MANAGER ); - if ( name ) { - xcb_xrm_database_t *xDB = xcb_xrm_database_from_string ( name ); - __config_parse_xresource_options_dynamic ( xDB, CONFIG_XRESOURCES ); - xcb_xrm_database_free ( xDB ); - g_free ( name ); + else if ( option->type == xrm_Number ) { + if ( p->type != P_INTEGER ) { + fprintf ( stderr, "Option: %s needs to be set with a number.\n", option->name ); + return; + } + *( option->value.snum ) = p->value.i; + option->source = CONFIG_FILE_THEME; + } + else if ( option->type == xrm_SNumber ) { + if ( p->type != P_INTEGER ) { + fprintf ( stderr, "Option: %s needs to be set with a number.\n", option->name ); + return; + } + *( option->value.num ) = (unsigned int ) ( p->value.i ); + option->source = CONFIG_FILE_THEME; + } + else if ( option->type == xrm_Boolean ) { + if ( p->type != P_BOOLEAN ) { + fprintf ( stderr, "Option: %s needs to be set with a boolean.\n", option->name ); + return; + } + *( option->value.num ) = ( p->value.b ); + option->source = CONFIG_FILE_THEME; } } -void config_parse_xresource_options_dynamic_file ( const char *filename ) + +void config_parse_set_property ( const Property *p ) { - if ( !filename ) { - return; + for ( unsigned int i = 0; i < sizeof ( xrmOptions ) / sizeof ( XrmOption ); ++i ) { + X |