diff --git a/doc/rofi.1.markdown b/doc/rofi.1.markdown index f2db1d653..1193646c9 100644 --- a/doc/rofi.1.markdown +++ b/doc/rofi.1.markdown @@ -302,6 +302,12 @@ Use Pango markup to format output wherever possible. Make **rofi** react like a normal application window. Useful for scripts like Clerk that are basically an application. +`-transient-window` + +Make **rofi** react like a modal dialog that is transient to the currently +focused window. Useful when you use a keyboard shortcut to run and show +on the window you are working with. + `-[no-]steal-focus` Make rofi steal focus on launch and restore close to window that held it when diff --git a/include/view.h b/include/view.h index 783d6f4a6..cef073e1c 100644 --- a/include/view.h +++ b/include/view.h @@ -56,6 +56,8 @@ typedef enum { MENU_NORMAL_WINDOW = 2, /** ERROR dialog */ MENU_ERROR_DIALOG = 4, + /** Create transient window. */ + MENU_TRANSIENT_WINDOW = 8, } MenuFlags; /** diff --git a/source/rofi.c b/source/rofi.c index 3d6917f8e..9ebe28df6 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -326,6 +326,9 @@ static void print_main_application_options(int is_term) { is_term); print_help_msg("-normal-window", "", "Behave as a normal window. (experimental)", NULL, is_term); + print_help_msg("-transient-window", "", + "Behave as a modal dialog that is transient to the currently " + "focused window. (experimental)", NULL, is_term); print_help_msg("-show", "[mode]", "Show the mode 'mode' and exit. The mode has to be enabled.", NULL, is_term); @@ -768,6 +771,9 @@ static gboolean startup(G_GNUC_UNUSED gpointer data) { if (find_arg("-normal-window") >= 0) { window_flags |= MENU_NORMAL_WINDOW; } + if (find_arg("-transient-window") >= 0) { + window_flags |= MENU_TRANSIENT_WINDOW; + } TICK_N("Grab keyboard"); __create_window(window_flags); TICK_N("Create Window"); diff --git a/source/view.c b/source/view.c index aac8c22ee..712f1aa71 100644 --- a/source/view.c +++ b/source/view.c @@ -1120,7 +1120,25 @@ void __create_window(MenuFlags menu_flags) { TICK_N("textbox setup"); // // make it an unmanaged window - if (((menu_flags & MENU_NORMAL_WINDOW) == 0)) { + if (((menu_flags & MENU_TRANSIENT_WINDOW) != 0)) { + xcb_atom_t atoms[] = {xcb->ewmh._NET_WM_STATE_MODAL}; + + window_set_atom_prop(box_window, xcb->ewmh._NET_WM_STATE, atoms, + sizeof(atoms) / sizeof(xcb_atom_t)); + window_set_atom_prop (box_window, xcb->ewmh._NET_WM_WINDOW_TYPE, + &(xcb->ewmh._NET_WM_WINDOW_TYPE_UTILITY), 1); + x11_disable_decoration(box_window); + + xcb_window_t active_window; + xcb_get_property_cookie_t awc; + awc = xcb_ewmh_get_active_window (&xcb->ewmh, xcb->screen_nbr); + + if (xcb_ewmh_get_active_window_reply(&xcb->ewmh, awc, &active_window, NULL)) { + xcb_change_property(xcb->connection, XCB_PROP_MODE_REPLACE, box_window, + XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32, + 1, &active_window); + } + } else if (((menu_flags & MENU_NORMAL_WINDOW) == 0)) { window_set_atom_prop(box_window, xcb->ewmh._NET_WM_STATE, &(xcb->ewmh._NET_WM_STATE_ABOVE), 1); uint32_t values[] = {1}; diff --git a/source/xcb.c b/source/xcb.c index 2b50ccb0c..6ad34b538 100644 --- a/source/xcb.c +++ b/source/xcb.c @@ -1898,7 +1898,7 @@ gboolean display_late_setup(void) { // Try to grab the keyboard as early as possible. // We grab this using the rootwindow (as dmenu does it). // this seems to result in the smallest delay for most people. - if (find_arg("-normal-window") >= 0) { + if (find_arg("-normal-window") >= 0 || find_arg("-transient-window") >= 0) { return TRUE; } if (find_arg("-no-lazy-grab") >= 0) {