X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=scripts%2Ffocus.py;h=667f92d7a8da641ddcf5bfed44662086d69fdb6e;hb=8934a553dcfbb0ea6035d2de8ed86595d3703f5a;hp=a80f9bb85443cd178e67b25d46851947bedaf5da;hpb=98a131603cfb09d01d13086f31955841fbed5dfc;p=chaz%2Fopenbox diff --git a/scripts/focus.py b/scripts/focus.py index a80f9bb8..667f92d7 100644 --- a/scripts/focus.py +++ b/scripts/focus.py @@ -5,15 +5,38 @@ ########################################################################### ### Options that affect the behavior of the focus module. ### ### ### -# raise the window also when it is focused ### +# cycle_raise - raise the window also when it is focused ### cycle_raise = 1 ### -# raise as you cycle in stacked mode ### +# avoid_skip_taskbar - Don't focus windows which have requested to not ### +### be displayed in taskbars. You will still be able ### +### to focus the windows, but not through cycling, ### +### and they won't be focused as a fallback if ### +### 'fallback' is enabled. ### +avoid_skip_taskbar = 1 ### +# stacked_cycle_raise - raise as you cycle in stacked mode ### stacked_cycle_raise = 0 ### -# show a pop-up list of windows while cycling ### +# stacked_cycle_popup_list - 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 @@ -32,7 +55,7 @@ def _new_win(data): if _doing_stacked: _clients.insert(_clients.index(_cyc_w), data.client.window()) _create_popup_list(data) - _hilite_popup_list() + _hilite_popup_list(data) else: if not len(_clients): _clients.append(data.client.window()) @@ -68,15 +91,20 @@ def _focused(data): _clients.insert(0, win) else: # if we are cycling, then update our pointer _cyc_w = data.client.window() - _hilite_popup_list() + _hilite_popup_list(data) elif fallback: # pass around focus desktop = ob.openbox.screen(_cyc_screen).desktop() for w in _clients: client = ob.openbox.findClient(w) - if client and (client.desktop() == desktop and \ - client.normal() and client.focus()): + if client and not (avoid_skip_taskbar and client.skipTaskbar()) \ + and (client.desktop() == desktop or + client.desktop() == 0xffffffff) \ + and client.normal() and client.focus(): break + if _doing_stacked: + _cyc_w = 0 + _hilite_popup_list(data) _cyc_mask = 0 _cyc_key = 0 @@ -102,8 +130,10 @@ def _do_stacked_cycle(data, forward): desktop = ob.openbox.screen(data.screen).desktop() for w in clients: client = ob.openbox.findClient(w) - if client and (client.desktop() == desktop and \ - client.normal() and client.focus()): + + if client and not (avoid_skip_taskbar and client.skipTaskbar()) and \ + (client.desktop() == desktop or client.desktop() == 0xffffffff)\ + and client.normal() and client.focus(): if stacked_cycle_raise: ob.openbox.screen(data.screen).raiseWindow(client) return @@ -116,27 +146,38 @@ 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: - ob.kungrab() # ungrab ourself + _destroy_popup_list() + ob.kungrab() + ob.mungrab() _doing_stacked = 0; if cycle_raise: client = ob.openbox.findClient(_cyc_w) if client: ob.openbox.screen(data.screen).raiseWindow(client) - _destroy_popup_list() _list_widget = 0 _list_labels = [] _list_windows = [] -def _hilite_popup_list(): - global _cyc_w +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() - else: _list_labels[i].unfocus() + 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 @@ -146,6 +187,7 @@ def _destroy_popup_list(): _list_widget = 0 def _create_popup_list(data): + global avoid_skip_taskbar global _list_widget, _list_labels, _list_windows, _clients if _list_widget: @@ -165,23 +207,24 @@ def _create_popup_list(data): for c in _clients: client = ob.openbox.findClient(c) desktop = ob.openbox.screen(data.screen).desktop() - if client and (client.desktop() == desktop and \ - client.normal()): + if client and not (avoid_skip_taskbar and client.skipTaskbar()) 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) + 10 # add margin + l = font.measureString(t) if l > longest: longest = l - if len(titles): + if len(titles) > 1: for t in titles: w = otk.FocusLabel(_list_widget) - w.resize(longest, height) + w.fitSize(longest, height) w.setText(t) w.unfocus() _list_labels.append(w) - _list_labels[0].focus() _list_widget.update() area = otk.display.screenInfo(data.screen).rect() _list_widget.move(area.x() + (area.width() - @@ -190,7 +233,7 @@ def _create_popup_list(data): _list_widget.height()) / 2) _list_widget.show(1) else: - _list_widget = 0 #nothing to list + _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 @@ -216,6 +259,10 @@ def focus_next_stacked(data, forward=1): _create_popup_list(data) ob.kgrab(data.screen, _focus_stacked_ungrab) + # the pointer grab causes pointer events during the keyboard grab to + # go away, which means we don't get enter notifies when the popup + # disappears, screwing up the focus + ob.mgrab(data.screen) focus_next_stacked(data, forward) # start with the first press def focus_prev_stacked(data): @@ -225,6 +272,8 @@ def focus_prev_stacked(data): def focus_next(data, num=1, forward=1): """Focus the next (or previous, with forward=0) window in a linear order.""" + global avoid_skip_taskbar + screen = ob.openbox.screen(data.screen) count = screen.clientCount() @@ -252,9 +301,10 @@ def focus_next(data, num=1, forward=1): curdesk = screen.desktop() while 1: client = screen.client(t) - if client.normal() and \ - (client.desktop() == curdesk or client.desktop() == 0xffffffff)\ - and client.focus(): + if not (avoid_skip_taskbar and client.skipTaskbar()) and \ + client.normal() and (client.desktop() == curdesk or + client.desktop() == 0xffffffff)\ + and client.focus(): if cycle_raise: screen.raiseWindow(client) return