summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Davenport <qball@gmpclient.org>2021-06-30 13:29:54 +0200
committerDave Davenport <qball@gmpclient.org>2021-06-30 13:29:54 +0200
commitc9701b2a9199ef7fe3348246232399449ca9416b (patch)
tree1e3a20cc7831f04820a28ea30ad470668831c579
parent42dde494c1a4ff7d6b49259fff94007541497314 (diff)
[View] Add support for user timeout + keybinding action
Configuration looks like: ```css configuration { timeout { delay: 15; action: "kb-cancel"; } } ``` Both delay and action need to be set. Action can be any of the keybindings as shown in `rofi -show keys`. (-timeout-delay 15 -timeout-action "kb-cancel" on commandline.). Fixes: #1066
-rw-r--r--include/keyb.h6
-rw-r--r--source/keyb.c12
-rw-r--r--source/mode.c2
-rw-r--r--source/view.c51
4 files changed, 70 insertions, 1 deletions
diff --git a/include/keyb.h b/include/keyb.h
index 67c49432..1cf33254 100644
--- a/include/keyb.h
+++ b/include/keyb.h
@@ -186,5 +186,11 @@ gboolean parse_keys_abe ( NkBindings *bindings );
*/
void setup_abe ( void );
+/**
+ * @param name Don't have the name.
+ *
+ * @returns id, or UINT32_MAX if not found.
+ */
+guint key_binding_get_action_from_name ( const char *name );
/**@}*/
#endif // ROFI_KEYB_H
diff --git a/source/keyb.c b/source/keyb.c
index edda3b75..04350bdf 100644
--- a/source/keyb.c
+++ b/source/keyb.c
@@ -147,6 +147,18 @@ static gboolean binding_trigger_action ( guint64 scope, G_GNUC_UNUSED gpointer t
return rofi_view_trigger_action ( rofi_view_get_active (), scope, GPOINTER_TO_UINT ( user_data ) );
}
+guint key_binding_get_action_from_name ( const char *name )
+{
+ for ( gsize i = 0; i < G_N_ELEMENTS ( rofi_bindings ); ++i ) {
+ ActionBindingEntry *b = &rofi_bindings[i];
+ if ( g_strcmp0(b->name, name) == 0 ){
+ return b->id;
+ }
+ }
+ return UINT32_MAX;
+}
+
+
gboolean parse_keys_abe ( NkBindings *bindings )
{
GError *error = NULL;
diff --git a/source/mode.c b/source/mode.c
index ae4b23be..5323cb25 100644
--- a/source/mode.c
+++ b/source/mode.c
@@ -157,7 +157,7 @@ const char *mode_get_display_name ( const Mode *mode )
ThemeWidget *wid = rofi_config_find_widget ( mode->name, NULL, TRUE );
if ( wid ) {
/** Check string property */
- Property *p = rofi_theme_find_property ( wid, P_STRING, "display-name", FALSE );
+ Property *p = rofi_theme_find_property ( wid, P_STRING, "display-name", TRUE );
if ( p != NULL && p->type == P_STRING ) {
return p->value.s;
}
diff --git a/source/view.c b/source/view.c
index 414603aa..656a4817 100644
--- a/source/view.c
+++ b/source/view.c
@@ -112,6 +112,8 @@ struct
workarea mon;
/** timeout for reloading */
guint idle_timeout;
+ /** timeout handling */
+ guint user_timeout;
/** debug counter for redraws */
unsigned long long count;
/** redraw idle time. */
@@ -129,6 +131,7 @@ struct
.flags = MENU_NORMAL,
.views = G_QUEUE_INIT,
.idle_timeout = 0,
+ .user_timeout = 0,
.count = 0L,
.repaint_source = 0,
.fullscreen = FALSE,
@@ -475,6 +478,48 @@ static gboolean rofi_view_reload_idle ( G_GNUC_UNUSED gpointer data )
CacheState.idle_timeout = 0;
return G_SOURCE_REMOVE;
}
+static gboolean rofi_view_user_timeout ( G_GNUC_UNUSED gpointer data )
+{
+ CacheState.user_timeout = 0;
+ ThemeWidget *wid = rofi_config_find_widget ( "timeout", NULL, TRUE );
+ if ( wid ) {
+ /** Check string property */
+ Property *p = rofi_theme_find_property ( wid, P_STRING, "action", TRUE);
+ if ( p != NULL && p->type == P_STRING ) {
+ const char *action = p->value.s;
+ guint id = key_binding_get_action_from_name(action);
+ if ( id != UINT32_MAX )
+ {
+ rofi_view_trigger_action ( rofi_view_get_active (), SCOPE_GLOBAL, id);
+ } else {
+ g_warning("Failed to parse keybinding: %s\r\n", action);
+ }
+ }
+ }
+ return G_SOURCE_REMOVE;
+}
+
+static void rofi_view_set_user_timeout ( G_GNUC_UNUSED gpointer data )
+{
+ if ( CacheState.user_timeout > 0 ) {
+ g_source_remove ( CacheState.user_timeout );
+ CacheState.user_timeout = 0;
+ }
+ {
+ /** Find the widget */
+ ThemeWidget *wid = rofi_config_find_widget ( "timeout", NULL, TRUE );
+ if ( wid ) {
+ /** Check string property */
+ Property *p = rofi_theme_find_property ( wid, P_INTEGER, "delay", TRUE);
+ if ( p != NULL && p->type == P_INTEGER) {
+ int delay = p->value.i;
+ CacheState.user_timeout = g_timeout_add ( delay*1000 , rofi_view_user_timeout, NULL );
+ }
+ }
+ }
+
+}
+
void rofi_view_reload ( void )
{
@@ -1996,6 +2041,8 @@ RofiViewState *rofi_view_create ( Mode *sw,
rofi_view_ping_mouse ( state );
xcb_flush ( xcb->connection );
+
+ rofi_view_set_user_timeout ( NULL );
/* When Override Redirect, the WM will not let us know we can take focus, so just steal it */
if ( ( ( menu_flags & MENU_NORMAL_WINDOW ) == 0 ) ) {
rofi_xcb_set_input_focus ( CacheState.main_window );
@@ -2066,6 +2113,10 @@ void rofi_view_cleanup ()
g_source_remove ( CacheState.idle_timeout );
CacheState.idle_timeout = 0;
}
+ if ( CacheState.user_timeout > 0 ) {
+ g_source_remove ( CacheState.user_timeout );
+ CacheState.user_timeout = 0;
+ }
if ( CacheState.repaint_source > 0 ) {
g_source_remove ( CacheState.repaint_source );
CacheState.repaint_source = 0;