LINUX.ORG.RU

[openbox] Переключать рабочие столы прямо из alt-tab-ового списка окон

 


0

2

Посетила указанная в заголовке юзабилити-идея. В самом деле, если по нажатию alt-tab, WM переходит в режим листания окон, то почему бы прямо оттуда же и не листать рабочие столы? Сказано — сделано. Патч добавляет опенбоксу листание столов по стрелке-влево/стрелке-вправо когда активен список окон:

diff --git a/openbox/actions/cyclewindows.c b/openbox/actions/cyclewindows.c
index 5f0db27..a3cde57 100644
--- a/openbox/actions/cyclewindows.c
+++ b/openbox/actions/cyclewindows.c
@@ -4,6 +4,7 @@
 #include "openbox/event.h"
 #include "openbox/focus_cycle.h"
 #include "openbox/openbox.h"
+#include "openbox/screen.h"
 #include "gettext.h"
 #include "obt/keyboard.h"
 
@@ -23,6 +24,8 @@ typedef struct {
     /* options for after we're done */
     gboolean cancel; /* did the user cancel or not */
     guint state;     /* keyboard state when finished */
+
+    guint screen_desktop;
 } Options;
 
 static gpointer setup_func(xmlNodePtr node,
@@ -70,6 +73,8 @@ static gpointer setup_func(xmlNodePtr node,
     o->bar = TRUE;
     o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_LIST;
 
+    o->screen_desktop = screen_desktop;
+
     if ((n = obt_xml_find_node(node, "linear")))
         o->linear = obt_xml_node_bool(n);
     if ((n = obt_xml_find_node(node, "dialog"))) {
@@ -206,6 +211,16 @@ static gboolean i_input_func(guint initial_state,
             o->state = e->xkey.state;
             return FALSE;
         }
+
+        else if ((sym == XK_Left || sym == XK_Right) ) {
+            guint d = screen_find_desktop(screen_desktop,
+                                          sym == XK_Right ? OB_DIRECTION_EAST : OB_DIRECTION_WEST, TRUE, TRUE);
+
+            screen_set_desktop(d, TRUE, FALSE);
+            run_func(NULL, options);
+            screen_show_desktop_popup(d, FALSE, FALSE);
+            return TRUE;
+        }
     }
     /* They released the modifiers */
     else if (e->type == KeyRelease && initial_state && !(mods & initial_state))
@@ -223,6 +238,8 @@ static void i_cancel_func(gpointer options)
     Options *o = options;
     o->cancel = TRUE;
     o->state = 0;
+
+    screen_set_desktop(o->screen_desktop, TRUE, TRUE);
 }
 
 static void i_post_func(gpointer options)
diff --git a/openbox/actions/desktop.c b/openbox/actions/desktop.c
index a3a1f6b..7886b7c 100644
--- a/openbox/actions/desktop.c
+++ b/openbox/actions/desktop.c
@@ -302,7 +302,7 @@ static gboolean run_func(ObActionsData *data, gpointer options)
         }
 
         if (go) {
-            screen_set_desktop(d, TRUE);
+            screen_set_desktop(d, TRUE, TRUE);
             if (data->client)
                 client_bring_helper_windows(data->client);
         }
@@ -356,7 +356,7 @@ static gboolean i_pre_func(guint initial_state, gpointer options)
         return FALSE;
     }
     else {
-        screen_show_desktop_popup(screen_desktop, TRUE);
+        screen_show_desktop_popup(screen_desktop, TRUE, TRUE);
         return TRUE;
     }
 }
diff --git a/openbox/client.c b/openbox/client.c
index f3b4bda..feff3a6 100644
--- a/openbox/client.c
+++ b/openbox/client.c
@@ -4029,7 +4029,7 @@ static void client_present(ObClient *self, gboolean here, gboolean raise,
         if (here)
             client_set_desktop(self, screen_desktop, FALSE, TRUE);
         else
-            screen_set_desktop(self->desktop, FALSE);
+            screen_set_desktop(self->desktop, FALSE, TRUE);
     } else if (!self->frame->visible)
         /* if its not visible for other reasons, then don't mess
            with it */
diff --git a/openbox/client_list_combined_menu.c b/openbox/client_list_combined_menu.c
index c26b6fa..f2027e4 100644
--- a/openbox/client_list_combined_menu.c
+++ b/openbox/client_list_combined_menu.c
@@ -126,10 +126,10 @@ static void menu_execute(ObMenuEntry *self, ObMenuFrame *f,
             /* if the window is omnipresent then we need to go to its
                desktop */
             if (!here && t->desktop == DESKTOP_ALL)
-                screen_set_desktop(self->id, FALSE);
+                screen_set_desktop(self->id, FALSE, TRUE);
         }
         else
-            screen_set_desktop(self->id, TRUE);
+            screen_set_desktop(self->id, TRUE, TRUE);
     }
 }
 
diff --git a/openbox/client_list_menu.c b/openbox/client_list_menu.c
index f3df2a5..0b5af55 100644
--- a/openbox/client_list_menu.c
+++ b/openbox/client_list_menu.c
@@ -106,10 +106,10 @@ static void desk_menu_execute(ObMenuEntry *self, ObMenuFrame *f,
         /* if the window is omnipresent then we need to go to its
            desktop */
         if (!here && t->desktop == DESKTOP_ALL)
-            screen_set_desktop(self->id, FALSE);
+            screen_set_desktop(self->id, FALSE, TRUE);
     }
     else
-        screen_set_desktop(self->id, TRUE);
+        screen_set_desktop(self->id, TRUE, TRUE);
 }
 
 static void desk_menu_destroy(ObMenu *menu, gpointer data)
diff --git a/openbox/event.c b/openbox/event.c
index cf089b6..d9d60a4 100644
--- a/openbox/event.c
+++ b/openbox/event.c
@@ -768,7 +768,7 @@ static void event_handle_root(XEvent *e)
                                   "a timestamp");
                 else
                     event_sourcetime = e->xclient.data.l[1];
-                screen_set_desktop(d, TRUE);
+                screen_set_desktop(d, TRUE, TRUE);
             }
         } else if (msgtype == OBT_PROP_ATOM(NET_NUMBER_OF_DESKTOPS)) {
             guint d = e->xclient.data.l[0];
diff --git a/openbox/moveresize.c b/openbox/moveresize.c
index 3a98db3..a776b7c 100644
--- a/openbox/moveresize.c
+++ b/openbox/moveresize.c
@@ -611,7 +611,7 @@ static gboolean edge_warp_delay_func(gpointer data)
         d = screen_find_desktop(screen_desktop, edge_warp_dir, TRUE, FALSE);
         if (d != screen_desktop) {
             if (config_mouse_screenedgewarp) edge_warp_move_ptr();
-            screen_set_desktop(d, TRUE);
+            screen_set_desktop(d, TRUE, TRUE);
         }
     }
     edge_warp_odd = !edge_warp_odd;
diff --git a/openbox/screen.c b/openbox/screen.c
index ffe74a0..5e69a32 100644
--- a/openbox/screen.c
+++ b/openbox/screen.c
@@ -433,13 +433,13 @@ void screen_startup(gboolean reconfig)
                        NET_CURRENT_DESKTOP, CARDINAL, &d) &&
         d < screen_num_desktops)
     {
-        screen_set_desktop(d, FALSE);
+        screen_set_desktop(d, FALSE, TRUE);
     } else if (session_desktop >= 0)
         screen_set_desktop(MIN((guint)session_desktop,
-                               screen_num_desktops), FALSE);
+                               screen_num_desktops), FALSE, TRUE);
     else
         screen_set_desktop(MIN(config_screen_firstdesk,
-                               screen_num_desktops) - 1, FALSE);
+                               screen_num_desktops) - 1, FALSE, TRUE);
     screen_last_desktop = screen_desktop;
 
     /* don't start in showing-desktop mode */
@@ -553,7 +553,7 @@ void screen_set_num_desktops(guint num)
 
     /* change our desktop if we're on one that no longer exists! */
     if (screen_desktop >= screen_num_desktops)
-        screen_set_desktop(num - 1, TRUE);
+        screen_set_desktop(num - 1, TRUE, TRUE);
 }
 
 static void screen_fallback_focus(void)
@@ -604,7 +604,7 @@ static gboolean last_desktop_func(gpointer data)
     return FALSE; /* don't repeat */
 }
 
-void screen_set_desktop(guint num, gboolean dofocus)
+void screen_set_desktop(guint num, gboolean dofocus, gboolean show_popup)
 {
     GList *it;
     guint previous;
@@ -689,8 +689,8 @@ void screen_set_desktop(guint num, gboolean dofocus)
 
     ob_debug("Moving to desktop %d", num+1);
 
-    if (ob_state() == OB_STATE_RUNNING)
-        screen_show_desktop_popup(screen_desktop, FALSE);
+    if (show_popup && ob_state() == OB_STATE_RUNNING)
+        screen_show_desktop_popup(screen_desktop, FALSE, TRUE);
 
     /* ignore enter events caused by the move */
     ignore_start = event_start_ignore_all_enters();
@@ -941,7 +941,7 @@ static gboolean hide_desktop_popup_func(gpointer data)
     return FALSE; /* don't repeat */
 }
 
-void screen_show_desktop_popup(guint d, gboolean perm)
+void screen_show_desktop_popup(guint d, gboolean perm, gboolean center)
 {
     const Rect *a;
 
@@ -949,8 +949,12 @@ void screen_show_desktop_popup(guint d, gboolean perm)
     if (!config_desktop_popup_time) return;
 
     a = screen_physical_area_primary(FALSE);
-    pager_popup_position(desktop_popup, CenterGravity,
-                         a->x + a->width / 2, a->y + a->height / 2);
+    if (center)
+        pager_popup_position(desktop_popup, CenterGravity,
+                             a->x + a->width / 2, a->y + a->height / 2);
+    else
+        pager_popup_position(desktop_popup, NorthGravity,
+                             a->x + a->width / 2, a->y);
     pager_popup_icon_size_multiplier(desktop_popup,
                                      (screen_desktop_layout.columns /
                                       screen_desktop_layout.rows) / 2,
diff --git a/openbox/screen.h b/openbox/screen.h
index a6a3995..af1aeb2 100644
--- a/openbox/screen.h
+++ b/openbox/screen.h
@@ -66,7 +66,7 @@ void screen_resize(void);
 /*! Change the number of available desktops */
 void screen_set_num_desktops(guint num);
 /*! Change the current desktop */
-void screen_set_desktop(guint num, gboolean dofocus);
+void screen_set_desktop(guint num, gboolean dofocus, gboolean show_popup);
 /*! Add a new desktop either at the end or inserted at the current desktop */
 void screen_add_desktop(gboolean current);
 /*! Remove a desktop, either at the end or the current desktop */
@@ -80,7 +80,7 @@ guint screen_find_desktop(guint from, ObDirection dir,
              screen_hide_desktop_popup().  Otherwise it will hide after a
              delay.
  */
-void screen_show_desktop_popup(guint d, gboolean permanent);
+void screen_show_desktop_popup(guint d, gboolean permanent, gboolean center);
 /*! Hide it */
 void screen_hide_desktop_popup(void);
 

Вроде очевидная фича, странно, что до сих пор нигде нет. Или это я в танке, и в каких-то других WM такое есть?

странно, что до сих пор нигде нет.

Сто лет уже есть в Гноме (C-M-стрелочки) и КДЕ (не помню).

power
()
Ответ на: комментарий от power

Сто лет уже есть в Гноме (C-M-стрелочки)

При чем тут базовые хоткеи. Задача была: добавить переключение в списко окон. Или Ъ даже заголовки тредов не читают?

geekless ★★
() автор топика
Ответ на: комментарий от geekless

Т.е. в списке окон показывать еще и рабочие столы?

Я читаю заголовки, но openbox не видел ни разу, хз что там и как.

power
()
Ответ на: комментарий от power

Т.е. в списке окон показывать еще и рабочие столы?

Жмешь alt-tab. Появляется список окон. Жмешь left. Происходит переход на следующий рабочий стол, список окон обновляется (окнами с этого стола).

geekless ★★
() автор топика
Ответ на: комментарий от anonymous

Пиши в рассылку

Рано. Во-первых, отмену я сделал неправильно. Вечером переделаю. Во-вторых, есть вопросы относительно логичности действий. Скажем, «alt-tab + left + отпустить alt» должно быть эквивалантно «переключиться на другой рабочий стол и выбрать следующее окно » или же просто «переключиться на другой рабочий стол»?

geekless ★★
() автор топика
Ответ на: комментарий от geekless

Не избыточно ли? Openbox умеет переключаться на окна на любом рабочем столе. Соответственно автоматом на на рабочий стол с активным окном перескакивает. По super+tab по-моему по умолчанию в боксе так устроено.

cyberstorm
()
Ответ на: комментарий от cyberstorm

Не избыточно. Щас у тебя 2 варианта: «плоский» переключатель окон по всем столам и «плоский» переключатель окон в пределах одного стола. Мой патч добавляет двумерности. Ты видишь окна только текущего стола, но одновременно можешь переключать рабочие столы.

geekless ★★
() автор топика

По-моему, client-list-combined-menu использовать будет быстрее и удобнее.

GotF ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.