]> Dogcows Code - chaz/openbox/blobdiff - scripts/focus.py
add motion.py, which provides funtions for moving/resizing a window interactively
[chaz/openbox] / scripts / focus.py
index 3ea42edc7023a850777cc88abe6033b2f9ce6f4a..adba37258fb89ed93a885e010b9165c9abad065e 100644 (file)
@@ -9,11 +9,30 @@
 cycle_raise = 1                                                         ###
 # raise as you cycle in stacked mode                                    ###
 stacked_cycle_raise = 0                                                 ###
+# show a pop-up list of windows while cycling                           ###
+stacked_cycle_popup_list = 1                                            ###
 # send focus somewhere when nothing is left with the focus, if possible ###
 fallback = 0                                                            ###
 ###                                                                     ###
+###                                                                     ###
+# Provides:                                                             ###
+# def focus_next_stacked(data, forward=1):                              ###
+#   """Focus the next (or previous, with forward=0) window in a stacked ###
+#      order."""                                                        ###
+# def focus_prev_stacked(data):                                         ###
+#   """Focus the previous window in a stacked order."""                 ###
+# def focus_next(data, num=1, forward=1):                               ###
+#   """Focus the next (or previous, with forward=0) window in a linear  ###
+#      order."""                                                        ###
+# def focus_prev(data, num=1):                                          ###
+#   """Focus the previous window in a linear order."""                  ###
+###                                                                     ###
+# All of these functions call be used as callbacks for bindings         ###
+# directly.                                                             ###
+###                                                                     ###
 ###########################################################################
 
+import otk
 import ob
 
 # maintain a list of clients, stacked in focus order
@@ -28,6 +47,8 @@ def _new_win(data):
 
     if _doing_stacked:
         _clients.insert(_clients.index(_cyc_w), data.client.window())
+        _create_popup_list(data)
+        _hilite_popup_list(data)
     else:
         if not len(_clients):
             _clients.append(data.client.window())
@@ -46,8 +67,9 @@ def _close_win(data):
         # have to fix the cycling if we remove anything
         win = data.client.window()
         if _cyc_w == win:
-            _do_stacked_cycle(data) # cycle off the window first
+            _do_stacked_cycle(data, 1) # cycle off the window first, forward
         _clients.remove(win)
+        _create_popup_list(data)
 
 def _focused(data):
     global _clients
@@ -62,6 +84,7 @@ def _focused(data):
             _clients.insert(0, win)
         else: # if we are cycling, then update our pointer
             _cyc_w = data.client.window()
+            _hilite_popup_list(data)
     elif fallback: 
         # pass around focus
         desktop = ob.openbox.screen(_cyc_screen).desktop()
@@ -70,6 +93,9 @@ def _focused(data):
             if client and (client.desktop() == desktop and \
                            client.normal() and client.focus()):
                 break
+        if _doing_stacked:
+            _cyc_w = 0
+            _hilite_popup_list(data)
 
 _cyc_mask = 0
 _cyc_key = 0
@@ -109,6 +135,7 @@ def _focus_stacked_ungrab(data):
     if data.action == ob.KeyAction.Release:
         # have all the modifiers this started with been released?
         if not _cyc_mask & data.state:
+            _destroy_popup_list()
             ob.kungrab() # ungrab ourself
             _doing_stacked = 0;
             if cycle_raise:
@@ -116,6 +143,85 @@ def _focus_stacked_ungrab(data):
                 if client:
                     ob.openbox.screen(data.screen).raiseWindow(client)
 
+_list_widget = 0
+_list_labels = []
+_list_windows = []
+
+def _hilite_popup_list(data):
+    global _cyc_w, _doing_stacked
+    global _list_widget, _list_labels, _list_windows
+    found = 0
+
+    if not _list_widget and _doing_stacked:
+        _create_popup_list(data)
+    
+    if _list_widget:
+        i = 0
+        for w in _list_windows:
+            if w == _cyc_w:
+                _list_labels[i].focus()
+                found = 1
+            else:
+                _list_labels[i].unfocus()
+            i += 1
+    if not found:
+        _create_popup_list(data)
+
+def _destroy_popup_list():
+    global _list_widget, _list_labels, _list_windows
+    if _list_widget:
+        _list_windows = []
+        _list_labels = []
+        _list_widget = 0
+    
+def _create_popup_list(data):
+    global _list_widget, _list_labels, _list_windows, _clients
+
+    if _list_widget:
+        _destroy_popup_list()
+    
+    style = ob.openbox.screen(data.screen).style()
+    _list_widget = otk.Widget(ob.openbox, style,
+                              otk.Widget.Vertical, 0,
+                              style.bevelWidth(), 1)
+    t = style.titlebarFocusBackground()
+    _list_widget.setTexture(t)
+
+    titles = []
+    font = style.labelFont()
+    height = font.height()
+    longest = 0
+    for c in _clients:
+        client = ob.openbox.findClient(c)
+        desktop = ob.openbox.screen(data.screen).desktop()
+        if client and ((client.desktop() == desktop or
+                        client.desktop() == 0xffffffff) and \
+                       client.normal() and (client.canFocus() or
+                                            client.focusNotify())):
+            t = client.title()
+            if len(t) > 50: # limit the length of titles
+                t = t[:24] + "..." + t[-24:]
+            titles.append(t)
+            _list_windows.append(c)
+            l = font.measureString(t)
+            if l > longest: longest = l
+    if len(titles) > 1:
+        for t in titles:
+            w = otk.FocusLabel(_list_widget)
+            w.fitSize(longest, height)
+            w.setText(t)
+            w.unfocus()
+            _list_labels.append(w)
+        _list_widget.update()
+        area = otk.display.screenInfo(data.screen).rect()
+        _list_widget.move(area.x() + (area.width() -
+                                      _list_widget.width()) / 2,
+                          area.y() + (area.height() -
+                                      _list_widget.height()) / 2)
+        _list_widget.show(1)
+    else:
+        _destroy_popup_list() # nothing (or only 1) to list
+
 def focus_next_stacked(data, forward=1):
     """Focus the next (or previous, with forward=0) window in a stacked
        order."""
@@ -135,6 +241,10 @@ def focus_next_stacked(data, forward=1):
         _cyc_screen = data.screen
         _doing_stacked = 1
 
+        global stacked_cycle_popup_list
+        if stacked_cycle_popup_list:
+            _create_popup_list(data)
+
         ob.kgrab(data.screen, _focus_stacked_ungrab)
         focus_next_stacked(data, forward) # start with the first press
 
This page took 0.024823 seconds and 4 git commands to generate.