summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQC <qball@gmpclient.org>2015-03-27 20:28:53 +0100
committerQC <qball@gmpclient.org>2015-03-27 20:28:53 +0100
commitb21368c005ac7349ed1ade37512a864a494477ee (patch)
treeb11c9fdb2745dad04de81ca4a8047c05ac160289
parentf52b697dd4a4d973ee9223960baa8f7c00977324 (diff)
OO-ify the Switchers.
-rw-r--r--Changelog1
-rw-r--r--include/dialogs/run.h11
-rw-r--r--include/dialogs/script.h30
-rw-r--r--include/dialogs/ssh.h11
-rw-r--r--include/dialogs/window.h3
-rw-r--r--include/helper.h6
-rw-r--r--include/rofi.h65
-rw-r--r--source/dialogs/dmenu.c11
-rw-r--r--source/dialogs/run.c99
-rw-r--r--source/dialogs/script.c152
-rw-r--r--source/dialogs/ssh.c91
-rw-r--r--source/dialogs/window.c302
-rw-r--r--source/helper.c4
-rw-r--r--source/rofi.c206
14 files changed, 570 insertions, 422 deletions
diff --git a/Changelog b/Changelog
index 9584b77b..89cb7b7b 100644
--- a/Changelog
+++ b/Changelog
@@ -12,6 +12,7 @@
- Improve rendering of boxes (fixed height and margins)
- Fix modi switcher boxes size+layout.
- Reduce work on redraws (do not always calculate new size/position), set text, etc.
+ - OO-ify the switchers.
Cleanup:
- Do not lug argc,argv around everywhere.
diff --git a/include/dialogs/run.h b/include/dialogs/run.h
index 49701705..c95944f4 100644
--- a/include/dialogs/run.h
+++ b/include/dialogs/run.h
@@ -1,14 +1,5 @@
#ifndef __RUN_DIALOG_H__
#define __RUN_DIALOG_H__
-/**
- * @param input Pointer to the user-input string.
- * @param data Custom data pointer for callback.
- *
- * Run the run dialog
- *
- * @returns SwitcherMode selected by user.
- */
-SwitcherMode run_switcher_dialog ( char **input, void *data );
-
+extern Switcher run_mode;
#endif
diff --git a/include/dialogs/script.h b/include/dialogs/script.h
index effc8177..fed5189b 100644
--- a/include/dialogs/script.h
+++ b/include/dialogs/script.h
@@ -1,27 +1,6 @@
#ifndef __SCRIPT_DIALOG_H__
#define __SCRIPT_DIALOG_H__
-/**
- * Structure holds the arguments for the script_switcher.
- */
-typedef struct
-{
- /** Prompt to display. */
- char *name;
- /** The script */
- char *script_path;
-} ScriptOptions;
-
-
-/**
- * @param input Pointer to the user-input string.
- * @param data Custom data pointer for callback.
- *
- * Run the script dialog
- *
- * @returns SwitcherMode selected by user.
- */
-SwitcherMode script_switcher_dialog ( char **input, void *data );
/**
* @param str The input string to parse
@@ -31,12 +10,5 @@ SwitcherMode script_switcher_dialog ( char **input, void *data );
*
* @returns NULL when it fails, a newly allocated ScriptOptions when successful.
*/
-ScriptOptions *script_switcher_parse_setup ( const char *str );
-
-/**
- * @param sw Handle to the ScriptOption
- *
- * Free the ScriptOptions block.
- */
-void script_switcher_free_options ( void *data );
+Switcher *script_switcher_parse_setup ( const char *str );
#endif
diff --git a/include/dialogs/ssh.h b/include/dialogs/ssh.h
index dac52006..d6fbe572 100644
--- a/include/dialogs/ssh.h
+++ b/include/dialogs/ssh.h
@@ -1,14 +1,5 @@
#ifndef __SSH_DIALOG_H__
#define __SSH_DIALOG_H__
-/**
- * @param input Pointer to the user-input string.
- * @param data Custom data pointer for callback.
- *
- * Run the ssh dialog
- *
- * @returns SwitcherMode selected by user.
- */
-SwitcherMode ssh_switcher_dialog ( char **input, void *data );
-
+extern Switcher ssh_mode;
#endif
diff --git a/include/dialogs/window.h b/include/dialogs/window.h
index e6b6f727..af582596 100644
--- a/include/dialogs/window.h
+++ b/include/dialogs/window.h
@@ -1,6 +1,5 @@
#ifndef __WINDOW_DIALOG_H__
#define __WINDOW_DIALOG_H__
-SwitcherMode run_switcher_window ( char **input, G_GNUC_UNUSED void *data );
-
+extern Switcher window_mode;
#endif // __WINDOW_DIALOG_H__
diff --git a/include/helper.h b/include/helper.h
index bd76d9a3..f6cdba7f 100644
--- a/include/helper.h
+++ b/include/helper.h
@@ -1,6 +1,6 @@
#ifndef __HELPER_H__
#define __HELPER_H__
-
+#include "rofi.h"
/**
* @param string The input string.
* @param output Pointer to 2 dimensional array with parsed string.
@@ -105,7 +105,7 @@ int find_arg ( const char * const key );
*/
int token_match ( char **tokens, const char *input, int case_sensitive,
__attribute__( ( unused ) ) int index,
- __attribute__( ( unused ) ) void *data );
+ __attribute__( ( unused ) ) Switcher * data );
/**
* @param cmd The command to execute.
@@ -115,7 +115,7 @@ int token_match ( char **tokens, const char *input, int case_sensitive,
*
* @returns a valid file descriptor on success, or -1 on failure.
*/
-int execute_generator ( char * cmd ) __attribute__( ( nonnull ) );
+int execute_generator ( const char * cmd ) __attribute__( ( nonnull ) );
/**
* @param pidfile The pidfile to create.
diff --git a/include/rofi.h b/include/rofi.h
index 74999a4a..83480a44 100644
--- a/include/rofi.h
+++ b/include/rofi.h
@@ -2,6 +2,7 @@
#define __SIMPLESWITCHER_H__
#include <X11/X.h>
#include <glib.h>
+#include <textbox.h>
/**
@@ -9,7 +10,7 @@
*/
extern const char *cache_dir;
-
+typedef struct _Switcher Switcher;
/**
* Enum used to sum the possible states of ROFI.
*/
@@ -34,7 +35,7 @@ typedef enum
* @returns SwitcherMode
*/
typedef SwitcherMode ( *switcher_callback )( char **input, void *data );
-typedef void ( *switcher_callback_free_data )( void *data );
+typedef void ( *switcher_free )( Switcher *data );
/**
* State returned by the rofi window.
@@ -42,19 +43,21 @@ typedef void ( *switcher_callback_free_data )( void *data );
typedef enum
{
/** Entry is selected. */
- MENU_OK = 0,
+ MENU_OK = 0x1,
/** User canceled the operation. (e.g. pressed escape) */
- MENU_CANCEL = -1,
+ MENU_CANCEL = 0x2,
/** User requested a mode switch */
- MENU_NEXT = -2,
+ MENU_NEXT = 0x4,
/** Custom (non-matched) input was entered. */
- MENU_CUSTOM_INPUT = -3,
+ MENU_CUSTOM_INPUT = 0x8,
/** User wanted to delete entry from history. */
- MENU_ENTRY_DELETE = -4,
+ MENU_ENTRY_DELETE = 0x10,
/** User wants to jump to another switcher. */
- MENU_QUICK_SWITCH = -5,
+ MENU_QUICK_SWITCH = 0x20,
/** Go to the previous menu. */
- MENU_PREVIOUS = -6
+ MENU_PREVIOUS = 0x40,
+ /** Modifiers */
+ MENU_SHIFT = 0x1000
} MenuReturn;
@@ -69,7 +72,7 @@ typedef enum
*
* @returns 1 when it matches, 0 if not.
*/
-typedef int ( *menu_match_cb )( char **tokens, const char *input, int case_sensitive, int index, void *data );
+typedef int ( *menu_match_cb )( char **tokens, const char *input, int case_sensitive, int index, Switcher *data );
/**
* @param lines An array of strings to display.
@@ -87,9 +90,9 @@ typedef int ( *menu_match_cb )( char **tokens, const char *input, int case_sensi
* @returns The command issued (see MenuReturn)
*/
MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prompt,
- Time *time, int *shift,
+ Time *time,
menu_match_cb mmc, void *mmc_data,
- int *selected_line, int sorting ) __attribute__ ( ( nonnull ( 1, 3, 4, 9 ) ) );
+ int *selected_line, int sorting ) __attribute__ ( ( nonnull ( 1, 3, 4, 8 ) ) );
/**
* @param sig The caught signal
*
@@ -212,4 +215,42 @@ extern Settings config;
*/
void error_dialog ( const char *msg );
+/**
+ * Structure defining a switcher.
+ * It consists of a name, callback and if enabled
+ * a textbox for the sidebar-mode.
+ */
+struct _Switcher
+{
+ // Name (max 31 char long)
+ char name[32];
+ // Textbox used in the sidebar-mode.
+ textbox *tb;
+ // Keybindings (keysym and modmask)
+ char * keycfg;
+ char * keystr;
+ KeySym keysym;
+ unsigned int modmask;
+
+
+ /**
+ * A switcher normally consists of the following parts:
+ */
+ void ( *init )( struct _Switcher *sw );
+ char ** ( *get_data )( unsigned int *length, struct _Switcher *pd );
+ int ( *match )( char **tokens, const char *input, int case_sensitive, int index, struct _Switcher *data );
+ SwitcherMode ( *result )( int menu_retv, char **input, unsigned int selected_line, struct _Switcher *pd );
+ void ( *destroy )( struct _Switcher *pd );
+ // Token match.
+ menu_match_cb token_match;
+
+ // Pointer to private data.
+ void *private_data;
+
+ // Extra fields for script
+ void *ed;
+ // Free SWitcher
+ switcher_free free;
+};
+
#endif
diff --git a/source/dialogs/dmenu.c b/source/dialogs/dmenu.c
index b79c56d4..35f32273 100644
--- a/source/dialogs/dmenu.c
+++ b/source/dialogs/dmenu.c
@@ -83,13 +83,12 @@ int dmenu_switcher_dialog ( char **input )
find_arg_int ( "-l", &selected_line );
do {
- int shift = 0;
- int mretv = menu ( list, length, input, dmenu_prompt, NULL, &shift,
+ int mretv = menu ( list, length, input, dmenu_prompt, NULL,
token_match, NULL, &selected_line, FALSE );
// We normally do not want to restart the loop.
restart = FALSE;
- if ( mretv == MENU_OK && list[selected_line] != NULL ) {
+ if ( ( mretv & MENU_OK ) && list[selected_line] != NULL ) {
if ( number_mode ) {
fprintf ( stdout, "%d", selected_line );
}
@@ -98,20 +97,20 @@ int dmenu_switcher_dialog ( char **input )
}
fputc ( '\n', stdout );
fflush ( stdout );
- if ( shift ) {
+ if ( ( mretv & MENU_SHIFT ) ) {
restart = TRUE;
// Move to next line.
selected_line = MIN ( selected_line + 1, length - 1 );
}
retv = TRUE;
}
- else if ( mretv == MENU_CUSTOM_INPUT && *input != NULL && *input[0] != '\0' ) {
+ else if ( ( mretv & MENU_CUSTOM_INPUT ) && *input != NULL && *input[0] != '\0' ) {
if ( !number_mode ) {
fputs ( *input, stdout );
fputc ( '\n', stdout );
fflush ( stdout );
}
- if ( shift ) {
+ if ( ( mretv & MENU_SHIFT ) ) {
restart = TRUE;
// Move to next line.
selected_line = MIN ( selected_line + 1, length - 1 );
diff --git a/source/dialogs/run.c b/source/dialogs/run.c
index 946fe334..fc3cd039 100644
--- a/source/dialogs/run.c
+++ b/source/dialogs/run.c
@@ -152,9 +152,8 @@ static char ** get_apps_external ( char **retv, unsigned int *length, unsigned i
}
// No duplicate, add it.
- retv = g_realloc ( retv, ( ( *length ) + 2 ) * sizeof ( char* ) );
- retv[( *length )] = g_strdup ( buffer );
- retv[( *length ) + 1] = NULL;
+ retv = g_realloc ( retv, ( ( *length ) + 2 ) * sizeof ( char* ) );
+ retv[( *length )] = g_strdup ( buffer );
( *length )++;
@@ -162,14 +161,16 @@ static char ** get_apps_external ( char **retv, unsigned int *length, unsigned i
fclose ( inp );
}
}
+ retv[( *length ) ] = NULL;
return retv;
}
/**
* Internal spider used to get list of executables.
*/
-static char ** get_apps ( char **retv, unsigned int *length )
+static char ** get_apps ( unsigned int *length )
{
+ char **retv = NULL;
unsigned int num_favorites = 0;
char *path;
@@ -263,47 +264,85 @@ static char ** get_apps ( char **retv, unsigned int *length )
return retv;
}
-SwitcherMode run_switcher_dialog ( char **input, G_GNUC_UNUSED void *data )
+typedef struct _RunModePrivateData
+{
+ unsigned int id;
+ char **cmd_list;
+ unsigned int cmd_list_length;
+} RunModePrivateData;
+
+
+static void run_mode_init ( Switcher *sw )
{
- int shift = 0;
- int selected_line = 0;
- SwitcherMode retv = MODE_EXIT;
- // act as a launcher
- unsigned int cmd_list_length = 0;
- char **cmd_list = NULL;
- cmd_list = get_apps ( cmd_list, &cmd_list_length );
-
- if ( cmd_list == NULL ) {
- cmd_list = g_malloc_n ( 2, sizeof ( char * ) );
- cmd_list[0] = g_strdup ( "No applications found" );
- cmd_list[1] = NULL;
+ if ( sw->private_data == NULL ) {
+ RunModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
+ sw->private_data = (void *) pd;
}
+}
- int mretv = menu ( cmd_list, cmd_list_length, input, "run:",
- NULL, &shift, token_match, NULL, &selected_line,
- config.levenshtein_sort );
+static char ** run_mode_get_data ( unsigned int *length, Switcher *sw )
+{
+ RunModePrivateData *rmpd = (RunModePrivateData *) sw->private_data;
+ if ( rmpd->cmd_list == NULL ) {
+ rmpd->cmd_list_length = 0;
+ rmpd->cmd_list = get_apps ( &( rmpd->cmd_list_length ) );
+ }
+ *length = rmpd->cmd_list_length;
+ return rmpd->cmd_list;
+}
- if ( mretv == MENU_NEXT ) {
+static SwitcherMode run_mode_result ( int mretv, char **input, unsigned int selected_line, Switcher *sw )
+{
+ RunModePrivateData *rmpd = (RunModePrivateData *) sw->private_data;
+ SwitcherMode retv = MODE_EXIT;
+
+ int shift = ( ( mretv & MENU_SHIFT ) == MENU_SHIFT );
+
+ if ( mretv & MENU_NEXT ) {
retv = NEXT_DIALOG;
}
- else if ( mretv == MENU_PREVIOUS ) {
+ else if ( mretv & MENU_PREVIOUS ) {
retv = PREVIOUS_DIALOG;
}
- else if ( mretv == MENU_QUICK_SWITCH ) {
+ else if ( mretv & MENU_QUICK_SWITCH ) {
retv = selected_line;
}
- else if ( mretv == MENU_OK && cmd_list[selected_line] != NULL ) {
- exec_cmd ( cmd_list[selected_line], shift );
+ else if ( ( mretv & MENU_OK ) && rmpd->cmd_list[selected_line] != NULL ) {
+ exec_cmd ( rmpd->cmd_list[selected_line], shift );
}
- else if ( mretv == MENU_CUSTOM_INPUT && *input != NULL && *input[0] != '\0' ) {
+ else if ( ( mretv & MENU_CUSTOM_INPUT ) && *input != NULL && *input[0] != '\0' ) {
exec_cmd ( *input, shift );
}
- else if ( mretv == MENU_ENTRY_DELETE && cmd_list[selected_line] ) {
- delete_entry ( cmd_list[selected_line] );
+ else if ( ( mretv & MENU_ENTRY_DELETE ) && rmpd->cmd_list[selected_line] ) {
+ delete_entry ( rmpd->cmd_list[selected_line] );
retv = RELOAD_DIALOG;
}
+ return retv;
+}
- g_strfreev ( cmd_list );
- return retv;
+static void run_mode_destroy ( Switcher *sw )
+{
+ RunModePrivateData *rmpd = (RunModePrivateData *) sw->private_data;
+ if ( rmpd != NULL ) {
+ g_strfreev ( rmpd->cmd_list );
+ g_free ( rmpd );
+ sw->private_data = NULL;
+ }
}
+
+Switcher run_mode =
+{
+ .name = "run",
+ .tb = NULL,
+ .keycfg = NULL,
+ .keystr = NULL,
+ .modmask = AnyModifier,
+ .init = run_mode_init,
+ .get_data = run_mode_get_data,
+ .result = run_mode_result,
+ .destroy = run_mode_destroy,
+ .token_match = token_match,
+ .private_data = NULL,
+ .free = NULL
+};
diff --git a/source/dialogs/script.c b/source/dialogs/script.c
index 946f7be6..96334ed1 100644
--- a/source/dialogs/script.c
+++ b/source/dialogs/script.c
@@ -42,7 +42,7 @@
-static char **get_script_output ( char *command, unsigned int *length )
+static char **get_script_output ( const char *command, unsigned int *length )
{
char **retv = NULL;
@@ -70,101 +70,131 @@ static char **get_script_output ( char *command, unsigned int *length )
return retv;
}
-static char **execute_executor ( ScriptOptions *options, const char *result, unsigned int *length )
+static char **execute_executor ( Switcher *sw, const char *result, unsigned int *length )
{
char **retv = NULL;
char *arg = g_shell_quote ( result );
- char *command = g_strdup_printf ( "%s %s", options->script_path, arg );
+ char *command = g_strdup_printf ( "%s %s", (const char *) sw->ed, arg );
retv = get_script_output ( command, length );
g_free ( command );
g_free ( arg );
return retv;
}
-SwitcherMode script_switcher_dialog ( char **input, void *data )
+static void script_switcher_free ( Switcher *sw )
{
- ScriptOptions *options = (ScriptOptions *) data;
- assert ( options != NULL );
- int selected_line = 0;
- SwitcherMode retv = MODE_EXIT;
- unsigned int length = 0;
- char **list = get_script_output ( options->script_path, &length );
- char *prompt = g_strdup_printf ( "%s:", options->name );
-
- do {
- unsigned int new_length = 0;
- char **new_list = NULL;
- int mretv = menu ( list, length, input, prompt, NULL, NULL,
- token_match, NULL, &selected_line, FALSE );
-
- if ( mretv == MENU_NEXT ) {
- retv = NEXT_DIALOG;
- }
- else if ( mretv == MENU_PREVIOUS ) {
- retv = PREVIOUS_DIALOG;
- }
- else if ( mretv == MENU_QUICK_SWITCH ) {
- retv = selected_line;
- }
- else if ( mretv == MENU_OK && list[selected_line] != NULL ) {
- new_list = execute_executor ( options, list[selected_line], &new_length );
- }
- else if ( mretv == MENU_CUSTOM_INPUT && *input != NULL && *input[0] != '\0' ) {
- new_list = execute_executor ( options, *input, &new_length );
- }
+ if ( sw == NULL ) {
+ return;
+ }
+ g_free ( sw->ed );
+ g_free ( sw );
+}
- // Free old list.
- g_strfreev ( list );
- list = NULL;
+typedef struct _ScriptModePrivateData
+{
+ unsigned int id;
+ char **cmd_list;
+ unsigned int cmd_list_length;
+} ScriptModePrivateData;
- // If a new list was generated, use that an loop around.
- if ( new_list != NULL ) {
- list = new_list;
- length = new_length;
- g_free ( *input );
- *input = NULL;
- }
- } while ( list != NULL );
- g_free ( prompt );
- return retv;
+static void script_mode_init ( Switcher *sw )
+{
+ if ( sw->private_data == NULL ) {
+ ScriptModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
+ sw->private_data = (void *) pd;
+ }
+}
+static char ** script_mode_get_data ( unsigned int *length, Switcher *sw )
+{
+ ScriptModePrivateData *rmpd = (ScriptModePrivateData *) sw->private_data;
+ if ( rmpd->cmd_list == NULL ) {
+ rmpd->cmd_list_length = 0;
+ rmpd->cmd_list = get_script_output ( (const char *) sw->ed, &( rmpd->cmd_list_length ) );
+ }
+ *length = rmpd->cmd_list_length;
+ return rmpd->cmd_list;
}
-void script_switcher_free_options ( void *data )
+static SwitcherMode script_mode_result ( int mretv, char **input, unsigned int selected_line, Switcher *sw )
{
- ScriptOptions *sw = (ScriptOptions *) data;
- if ( sw == NULL ) {
- return;
+ ScriptModePrivateData *rmpd = (ScriptModePrivateData *) sw->private_data;
+ SwitcherMode retv = MODE_EXIT;
+ char **new_list = NULL;
+ unsigned int new_length = 0;
+
+ if ( ( mretv & MENU_NEXT ) ) {
+ retv = NEXT_DIALOG;
}
- g_free ( sw->name );
- g_free ( sw->script_path );
- g_free ( sw );
+ else if ( ( mretv & MENU_PREVIOUS ) ) {
+ retv = PREVIOUS_DIALOG;
+ }
+ else if ( ( mretv & MENU_QUICK_SWITCH ) ) {
+ retv = selected_line;
+ }
+ else if ( ( mretv & MENU_OK ) && rmpd->cmd_list[selected_line] != NULL ) {
+ new_list = execute_executor ( sw, rmpd->cmd_list[selected_line], &new_length );
+ }
+ else if ( ( mretv & MENU_CUSTOM_INPUT ) && *input != NULL && *input[0] != '\0' ) {
+ new_list = execute_executor ( sw, *input, &new_length );
+ }
+
+
+ // If a new list was generated, use that an loop around.
+ if ( new_list != NULL ) {
+ g_strfreev ( rmpd->cmd_list );
+
+ rmpd->cmd_list = new_list;
+ rmpd->cmd_list_length = new_length;
+ g_free ( *input );
+ *input = NULL;
+ retv = RELOAD_DIALOG;
+ }
+ return retv;
}
+static void script_mode_destroy ( Switcher *sw )
+{
+ ScriptModePrivateData *rmpd = (ScriptModePrivateData *) sw->private_data;
+ if ( rmpd != NULL ) {
+ g_strfreev ( rmpd->cmd_list );
+ g_free ( rmpd );
+ sw->private_data = NULL;
+ }
+}
-ScriptOptions *script_switcher_parse_setup ( const char *str )
+Switcher *script_switcher_parse_setup ( const char *str )
{
- ScriptOptions *sw = g_malloc0 ( sizeof ( *sw ) );
- char *endp = NULL;
- char *parse = g_strdup ( str );
- unsigned int index = 0;
+ Switcher *sw = g_malloc0 ( sizeof ( *sw ) );
+ char *endp = NULL;
+ char *parse = g_strdup ( str );
+ unsigned int index = 0;
for ( char *token = strtok_r ( parse, ":", &endp ); token != NULL; token = strtok_r ( NULL, ":", &endp ) ) {
if ( index == 0 ) {
- sw->name = g_strdup ( token );
+ g_strlcpy ( sw->name, token, 32 );
}
else if ( index == 1 ) {
- sw->script_path = g_strdup ( token );
+ sw->ed = (void *) g_strdup ( token );
}
index++;
}
g_free ( parse );
if ( index == 2 ) {
+ sw->free = script_switcher_free;
+ sw->keysym = None;
+ sw->modmask = AnyModifier;
+ sw->init = script_mode_init;
+ sw->get_data = script_mode_get_data;
+ sw->result = script_mode_result;
+ sw->destroy = script_mode_destroy;
+ sw->token_match = token_match;
+
return sw;
}
fprintf ( stderr, "The script command '%s' has %u options, but needs 2: <name>:<script>.\n",
str, index );
- script_switcher_free_options ( sw );
+ script_switcher_free ( sw );
return NULL;
}
diff --git a/source/dialogs/ssh.c b/source/dialogs/ssh.c
index 49c167c4..0498a2be 100644
--- a/source/dialogs/ssh.c
+++ b/source/dialogs/ssh.c
@@ -109,11 +109,11 @@ static int ssh_sort_func ( const void *a, const void *b )
const char *bstr = *( const char * const * ) b;
return g_utf8_collate ( astr, bstr );
}
-static char ** get_ssh ( unsigned int *length )
+static char ** get_ssh ( unsigned int *length )
{
+ char **retv = NULL;
unsigned int num_favorites = 0;
char *path;
- char **retv = NULL;
if ( getenv ( "HOME" ) == NULL ) {
return NULL;
@@ -191,47 +191,80 @@ static char ** get_ssh ( unsigned int *length )
return retv;
}
-SwitcherMode ssh_switcher_dialog ( char **input, G_GNUC_UNUSED void *data )
+typedef struct _SSHModePrivateData
{
- SwitcherMode retv = MODE_EXIT;
- // act as a launcher
- unsigned int cmd_list_length = 0;
- char **cmd_list = get_ssh ( &cmd_list_length );
-
- if ( cmd_list == NULL ) {
- cmd_list = g_malloc_n ( 2, sizeof ( char * ) );
- cmd_list[0] = g_strdup ( "No ssh hosts found" );
- cmd_list[1] = NULL;
- }
+ unsigned int id;
+ char **cmd_list;
+ unsigned int cmd_list_length;
+} SSHModePrivateData;
- int shift = 0;
- int selected_line = 0;
- int mretv = menu ( cmd_list, cmd_list_length, input, "ssh:",
- NULL, &shift, token_match, NULL, &selected_line,
- config.levenshtein_sort );
+static void ssh_mode_init ( Switcher *sw )
+{
+ if ( sw->private_data == NULL ) {
+ SSHModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
+ sw->private_data = (void *) pd;
+ }
+}
- if ( mretv == MENU_NEXT ) {
+static char ** ssh_mode_get_data ( unsigned int *length, Switcher *sw )
+{
+ SSHModePrivateData *rmpd = (SSHModePrivateData *) sw->private_data;
+ if ( rmpd->cmd_list == NULL ) {
+ rmpd->cmd_list_length = 0;
+ rmpd->cmd_list = get_ssh ( &( rmpd->cmd_list_length ) );
+ }
+ *length = rmpd->cmd_list_length;
+ return rmpd->cmd_list;
+}
+static SwitcherMode ssh_mode_result ( int mretv, char **input, unsigned int selected_line, Switcher *sw )
+{
+ SwitcherMode retv = MODE_EXIT;
+ SSHModePrivateData *rmpd = (SSHModePrivateData *) sw->private_data;
+ if ( mretv & MENU_NEXT ) {
retv = NEXT_DIALOG;
}
- else if ( mretv == MENU_PREVIOUS ) {
+ else if ( mretv & MENU_PREVIOUS ) {
retv = PREVIOUS_DIALOG;
}
- else if ( mretv == MENU_QUICK_SWITCH ) {
+ else if ( mretv & MENU_QUICK_SWITCH ) {
retv = selected_line;
}
- else if ( mretv == MENU_OK && cmd_list[selected_line] != NULL ) {
- exec_ssh ( cmd_list[selected_line] );
+ else if ( ( mretv & MENU_OK ) && rmpd->cmd_list[selected_line] != NULL ) {
+ exec_ssh ( rmpd->cmd_list[selected_line] );
}
- else if ( mretv == MENU_CUSTOM_INPUT && *input != NULL && *input[0] != '\0' ) {
+ else if ( ( mretv & MENU_CUSTOM_INPUT ) && *input != NULL && *input[0] != '\0' ) {
exec_ssh ( *input );
}
- else if ( mretv == MENU_ENTRY_DELETE && cmd_list[selected_line] ) {
- delete_ssh ( cmd_list[selected_line] );
+ else if ( ( mretv & MENU_ENTRY_DELETE ) && rmpd->cmd_list[selected_line] ) {
+ delete_ssh ( rmpd->cmd_list[selected_line] );
// Stay
retv = RELOAD_DIALOG;
}
-
- g_strfreev ( cmd_list );
-
return retv;
}
+
+static void ssh_mode_destroy ( Switcher *sw )
+{
+ SSHModePrivateData *rmpd = (SSHModePrivateData *) sw->private_data;
+ if ( rmpd != NULL ) {
+ g_strfreev ( rmpd->cmd_list );
+ g_free ( rmpd );
+ sw->private_data = NULL;
+ }
+}
+
+Switcher ssh_mode =
+{
+ .name = "ssh",
+ .tb = NULL,
+ .keycfg = NULL,
+ .keystr = NULL,
+ .modmask = AnyModifier,
+ .init = ssh_mode_init,
+ .get_data = ssh_mode_get_data,
+ .result = ssh_mode_result,
+ .destroy = ssh_mode_destroy,
+ .token_match = token_match,
+ .private_data = NULL,
+ .free = NULL
+};
diff --git a/source/dialogs/window.c b/source/dialogs/window.c
index deb4b54f..815f41a8 100644
--- a/source/dialogs/window.c
+++ b/source/dialogs/window.c
@@ -278,14 +278,23 @@ static client* window_client ( Display *display, Window win )
return c;
}
-
+typedef struct _SwitcherModePrivateData
+{
+ unsigned int id;
+ char **cmd_list;
+ unsigned int cmd_list_length;
+ winlist *ids;
+ int config_i3_mode;
+ int init;
+} SwitcherModePrivateData;
static int window_match ( char **tokens, __attribute__( ( unused ) ) const char *input,
- int case_sensitive, int index, void *data )
+ int case_sensitive, int index, Switcher *sw )
{
- int match = 1;
- winlist *ids = ( winlist * ) data;
- client *c = window_client ( display, ids->array[index] );
+ SwitcherModePrivateData *rmpd = (SwitcherModePrivateData *) sw->private_data;
+ int match = 1;
+ winlist *ids = ( winlist * ) rmpd->ids;
+ client *c = window_client ( display, ids->array[index] );
if ( tokens ) {
// Create collate keys.
@@ -324,149 +333,186 @@ static int window_match ( char **tokens, __attribute__( ( unused ) ) const char
return match;
}
-
-
-SwitcherMode run_switcher_window ( char **input, G_GNUC_UNUSED void *data )
+static void window_mode_init ( Switcher *sw )
{
- Screen *screen = DefaultScreenOfDisplay ( display );
- Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) );
- SwitcherMode retv = MODE_EXIT;
- // find window list
- Atom type;
- int nwins;
- Window wins[100];
- int count = 0;
- Window curr_win_id = 0;
- // Create cache
-
- x11_cache_create ();
- // Check for i3
- int config_i3_mode = i3_support_initialize ( display );
-
- // Get the active window so we can highlight this.
- if ( !( window_get_prop ( display, root, netatoms[_NET_ACTIVE_WINDOW], &type,
- &count, &curr_win_id, sizeof ( Window ) )
- && type == XA_WINDOW && count > 0 ) ) {
- curr_win_id = 0;
+ if ( sw->private_data == NULL ) {
+ SwitcherModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
+ sw->private_data = (void *) pd;
+ pd->init = FALSE;
}
+}
+
+static char ** window_mode_get_data ( unsigned int *length, Switcher *sw )
+{
+ SwitcherModePrivateData *pd = (SwitcherModePrivateData *) sw->private_data;
+ if ( !pd->init ) {
+ Screen *screen = DefaultScreenOfDisplay ( display );
+ Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) );
+ // find window list
+ Atom type;
+ int nwins;
+ Window wins[100];
+ int count = 0;
+ Window curr_win_id = 0;
+ // Create cache
+
+ x11_cache_create ();
+ // Check for i3
+ pd->config_i3_mode = i3_support_initialize ( display );
+
+ // Get the active window so we can highlight this.
+ if ( !( window_get_prop ( display, root, netatoms[_NET_ACTIVE_WINDOW], &type,
+ &count, &curr_win_id, sizeof ( Window ) )
+ && type == XA_WINDOW && count > 0 ) ) {
+ curr_win_id = 0;
+ }
- if ( window_get_prop ( display, root, netatoms[_NET_CLIENT_LIST_STACKING],
- &type, &nwins, wins, 100 * sizeof ( Window ) )
- && type == XA_WINDOW ) {
- char pattern[50];
- int i;
- unsigned int classfield = 0;
<