diff options
| author | Dana Jansens <danakj@orodu.net> | 2003-03-21 18:42:39 +0000 |
|---|---|---|
| committer | Dana Jansens <danakj@orodu.net> | 2003-03-21 18:42:39 +0000 |
| commit | a52a6d96d701c993896f276e4198003317632aaf (patch) | |
| tree | be2f51e6a433d1fdf9a7c8248b343cb3f6297212 /scripts | |
| parent | a36c7543d4eedaa9e10bfd9f4d9b81279b1bb7e6 (diff) | |
rm the old code including the .pys and the c++ shit
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/.cvsignore | 2 | ||||
| -rw-r--r-- | scripts/Makefile.am | 10 | ||||
| -rw-r--r-- | scripts/behavior.py | 115 | ||||
| -rw-r--r-- | scripts/callbacks.py | 284 | ||||
| -rw-r--r-- | scripts/config.py | 244 | ||||
| -rw-r--r-- | scripts/cycle.py | 473 | ||||
| -rw-r--r-- | scripts/defaults.py | 78 | ||||
| -rw-r--r-- | scripts/focus.py | 89 | ||||
| -rw-r--r-- | scripts/focusmodel.py | 61 | ||||
| -rw-r--r-- | scripts/historyplacement.py | 185 | ||||
| -rw-r--r-- | scripts/motion.py | 348 | ||||
| -rw-r--r-- | scripts/windowplacement.py | 50 |
12 files changed, 0 insertions, 1939 deletions
diff --git a/scripts/.cvsignore b/scripts/.cvsignore deleted file mode 100644 index 282522db..00000000 --- a/scripts/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile -Makefile.in diff --git a/scripts/Makefile.am b/scripts/Makefile.am deleted file mode 100644 index 01c1aa92..00000000 --- a/scripts/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -scriptdir = $(libdir)/openbox/python -MAINTAINERCLEANFILES = Makefile.in -script_PYTHON = config.py defaults.py focus.py callbacks.py \ - focusmodel.py windowplacement.py behavior.py motion.py \ - historyplacement.py cycle.py - -distclean-local: - $(RM) *\~ .\#* -uninstall-am: - rmdir -p $(scriptdir) diff --git a/scripts/behavior.py b/scripts/behavior.py deleted file mode 100644 index fd79b4f8..00000000 --- a/scripts/behavior.py +++ /dev/null @@ -1,115 +0,0 @@ -############################################################################### -### Functions for setting up some default behaviors. This includes the ### -### default bindings for clicking on various parts of a window, the ### -### titlebar buttons, and bindings for the scroll wheel on your mouse. ### -############################################################################### - -import ob -import callbacks -import motion - -def setup_window_clicks(): - """Sets up the default bindings for various mouse buttons for various - contexts. - This includes: - * Alt-left drag anywhere on a window will move it - * Alt-right drag anywhere on a window will resize it - * Left drag on a window's titlebar/handle will move it - * Left drag on a window's handle grips will resize it - * Alt-left press anywhere on a window's will raise it to the front of - its stacking layer. - * Left press on a window's titlebar/handle will raise it to the front - of its stacking layer. - * Alt-middle click anywhere on a window's will lower it to the bottom - of its stacking layer. - * Middle click on a window's titlebar/handle will lower it to the - bottom of its stacking layer. - * Double-left click on a window's titlebar will toggle shading it - """ - ob.mbind("A-Left", ob.MouseContext.Frame, - ob.MouseAction.Motion, motion.move) - ob.mbind("A-Left", ob.MouseContext.Frame, - ob.MouseAction.Release, motion.end_move) - ob.mbind("Left", ob.MouseContext.Titlebar, - ob.MouseAction.Motion, motion.move) - ob.mbind("Left", ob.MouseContext.Titlebar, - ob.MouseAction.Release, motion.end_move) - ob.mbind("Left", ob.MouseContext.Handle, - ob.MouseAction.Motion, motion.move) - ob.mbind("Left", ob.MouseContext.Handle, - ob.MouseAction.Release, motion.end_move) - - ob.mbind("A-Right", ob.MouseContext.Frame, - ob.MouseAction.Motion, motion.resize) - ob.mbind("A-Right", ob.MouseContext.Frame, - ob.MouseAction.Release, motion.end_resize) - ob.mbind("Left", ob.MouseContext.Grip, - ob.MouseAction.Motion, motion.resize) - ob.mbind("Left", ob.MouseContext.Grip, - ob.MouseAction.Release, motion.end_resize) - - ob.mbind("Left", ob.MouseContext.Titlebar, - ob.MouseAction.Press, callbacks.raise_win) - ob.mbind("Left", ob.MouseContext.Handle, - ob.MouseAction.Press, callbacks.raise_win) - ob.mbind("A-Left", ob.MouseContext.Frame, - ob.MouseAction.Press, callbacks.raise_win) - ob.mbind("A-Middle", ob.MouseContext.Frame, - ob.MouseAction.Click, callbacks.lower_win) - ob.mbind("Middle", ob.MouseContext.Titlebar, - ob.MouseAction.Click, callbacks.lower_win) - ob.mbind("Middle", ob.MouseContext.Handle, - ob.MouseAction.Click, callbacks.lower_win) - - ob.mbind("Left", ob.MouseContext.Titlebar, - ob.MouseAction.DoubleClick, callbacks.toggle_shade) - -def setup_window_buttons(): - """Sets up the default behaviors for the buttons in the window titlebar.""" - ob.mbind("Left", ob.MouseContext.AllDesktopsButton, - ob.MouseAction.Click, callbacks.toggle_all_desktops) - ob.mbind("Left", ob.MouseContext.CloseButton, - ob.MouseAction.Click, callbacks.close) - ob.mbind("Left", ob.MouseContext.IconifyButton, - ob.MouseAction.Click, callbacks.iconify) - ob.mbind("Left", ob.MouseContext.MaximizeButton, - ob.MouseAction.Click, callbacks.toggle_maximize) - ob.mbind("Middle", ob.MouseContext.MaximizeButton, - ob.MouseAction.Click, callbacks.toggle_maximize_vert) - ob.mbind("Right", ob.MouseContext.MaximizeButton, - ob.MouseAction.Click, callbacks.toggle_maximize_horz) - -def setup_scroll(): - """Sets up the default behaviors for the mouse scroll wheel. - This includes: - * scrolling on a window titlebar will shade/unshade it - * alt-scrolling anywhere will switch to the next/previous desktop - * control-alt-scrolling on a window will send it to the next/previous - desktop, and switch to the desktop with the window - """ - ob.mbind("Up", ob.MouseContext.Titlebar, - ob.MouseAction.Click, callbacks.shade) - ob.mbind("Down", ob.MouseContext.Titlebar, - ob.MouseAction.Click, callbacks.unshade) - - ob.mbind("A-Up", ob.MouseContext.Frame, - ob.MouseAction.Click, callbacks.next_desktop) - ob.mbind("A-Up", ob.MouseContext.Root, - ob.MouseAction.Click, callbacks.next_desktop) - ob.mbind("Up", ob.MouseContext.Root, - ob.MouseAction.Click, callbacks.next_desktop) - ob.mbind("A-Down", ob.MouseContext.Frame, - ob.MouseAction.Click, callbacks.prev_desktop) - ob.mbind("A-Down", ob.MouseContext.Root, - ob.MouseAction.Click, callbacks.prev_desktop) - ob.mbind("Down", ob.MouseContext.Root, - ob.MouseAction.Click, callbacks.prev_desktop) - - ob.mbind("C-A-Up", ob.MouseContext.Frame, - ob.MouseAction.Click, callbacks.send_to_next_desktop) - ob.mbind("C-A-Down", ob.MouseContext.Frame, - ob.MouseAction.Click, callbacks.send_to_prev_desktop) - -export_functions = setup_window_clicks, setup_window_buttons, setup_scroll - -print "Loaded behavior.py" diff --git a/scripts/callbacks.py b/scripts/callbacks.py deleted file mode 100644 index 0264626b..00000000 --- a/scripts/callbacks.py +++ /dev/null @@ -1,284 +0,0 @@ -############################################################################ -### Functions that can be used as callbacks for mouse/keyboard bindings ### -############################################################################ - -import ob -import otk - -def iconify(data): - """Iconifies the window on which the event occured""" - if not data.client: return - data.client.iconify(1) - -def restore(data): - """Un-iconifies the window on which the event occured, but does not focus - if. If you want to focus the window too, it is recommended that you - use the activate() function.""" - if not data.client: return - data.client.iconify(0) - -def close(data): - """Closes the window on which the event occured""" - if not data.client: return - data.client.close() - -def focus(data): - """Focuses the window on which the event occured""" - if not data.client: return - # !normal windows dont get focus from window enter events - if data.action == ob.EventAction.EnterWindow and not data.client.normal(): - return - data.client.focus() - -def raise_win(data): - """Raises the window on which the event occured""" - if not data.client: return - data.client.raiseWindow() - -def lower_win(data): - """Lowers the window on which the event occured""" - if not data.client: return - data.client.lowerWindow() - -def toggle_maximize(data): - """Toggles the maximized status of the window on which the event occured""" - if not data.client: return - data.client.maximize(not (data.client.maxHorz() or data.client.maxVert())) - -def toggle_maximize_horz(data): - """Toggles the horizontal maximized status of the window on which the event - occured""" - if not data.client: return - data.client.maximizeHorizontal(not data.client.maxHorz()) - -def toggle_maximize_vert(data): - """Toggles the vertical maximized status of the window on which the event - occured""" - if not data.client: return - data.client.maximizeVertical(not data.client.maxVert()) - -def maximize(data): - """Maximizes the window on which the event occured""" - if not data.client: return - data.client.maximize(1) - -def maximize_horz(data): - """Horizontally maximizes the window on which the event occured""" - if not data.client: return - data.client.maximizeHorizontal(1) - -def maximize_vert(data): - """Vertically maximizes the window on which the event occured""" - if not data.client: return - data.client.maximizeVertical(1) - -def unmaximize(data): - """Unmaximizes the window on which the event occured""" - if not data.client: return - data.client.maximize(0) - -def unmaximize_horz(data): - """Horizontally unmaximizes the window on which the event occured""" - if not data.client: return - data.client.maximizeHorizontal(0) - -def unmaximize_vert(data): - """Vertically unmaximizes the window on which the event occured""" - if not data.client: return - data.client.maximizeVertical(0) - -def toggle_shade(data): - """Toggles the shade status of the window on which the event occured""" - if not data.client: return - data.client.shade(not data.client.shaded()) - -def shade(data): - """Shades the window on which the event occured""" - if not data.client: return - data.client.shade(1) - -def unshade(data): - """Unshades the window on which the event occured""" - if not data.client: return - data.client.shade(0) - -def change_desktop(data, num): - """Switches to a specified desktop""" - ob.openbox.screen(data.screen).changeDesktop(num) - -def show_desktop(data, show=1): - """Shows and focuses the desktop, hiding any client windows. Optionally, - if show is zero, this will hide the desktop, leaving show-desktop - mode.""" - ob.openbox.screen(data.screen).showDesktop(show) - -def hide_desktop(data): - """Hides the desktop, re-showing the client windows. Leaves show-desktop - mode.""" - show_desktop(data, 0) - -def toggle_show_desktop(data): - """Requests the Openbox to show the desktop, hiding the client windows, or - redisplay the clients.""" - screen = ob.openbox.screen(data.screen) - screen.showDesktop(not screen.showingDesktop()) - -def next_desktop(data, no_wrap=0): - """Switches to the next desktop, optionally (by default) cycling around to - the first when going past the last.""" - screen = ob.openbox.screen(data.screen) - d = screen.desktop() - n = screen.numDesktops() - if (d < (n-1)): - d = d + 1 - elif not no_wrap: - d = 0 - change_desktop(data, d) - -def prev_desktop(data, no_wrap=0): - """Switches to the previous desktop, optionally (by default) cycling around - to the last when going past the first.""" - screen = ob.openbox.screen(data.screen) - d = screen.desktop() - n = screen.numDesktops() - if (d > 0): - d = d - 1 - elif not no_wrap: - d = n - 1 - change_desktop(data, d) - -def up_desktop(data, num=1): - """Switches to the desktop vertically above the current one. This is based - on the desktop layout chosen by an EWMH compliant pager. Optionally, num - can be specified to move more than one row at a time.""" - screen = ob.openbox.screen(data.screen) - d = screen.desktop() - n = screen.numDesktops() - l = screen.desktopLayout() - - target = d - num * l.columns - if target < 0: - target += l.rows * l.columns - while target >= n: - target -= l.columns - change_desktop(data, target) - -def down_desktop(data, num=1): - """Switches to the desktop vertically below the current one. This is based - on the desktop layout chosen by an EWMH compliant pager. Optionally, num - can be specified to move more than one row at a time.""" - screen = ob.openbox.screen(data.screen) - d = screen.desktop() - n = screen.numDesktops() - l = screen.desktopLayout() - - target = d + num * l.columns - if target >= n: - target -= l.rows * l.columns - while target < 0: - target += l.columns - change_desktop(data, target) - -def left_desktop(data, num=1): - """Switches to the desktop horizotally left of the current one. This is - based on the desktop layout chosen by an EWMH compliant pager. - Optionally, num can be specified to move more than one column at a - time.""" - screen = ob.openbox.screen(data.screen) - d = screen.desktop() - n = screen.numDesktops() - l = screen.desktopLayout() - - rowstart = d - d % l.columns - target = d - num - while target < rowstart: - target += l.columns - change_desktop(data, target) - -def right_desktop(data, num=1): - """Switches to the desktop horizotally right of the current one. This is - based on the desktop layout chosen by an EWMH compliant pager. - Optionally, num can be specified to move more than one column at a - time.""" - screen = ob.openbox.screen(data.screen) - d = screen.desktop() - n = screen.numDesktops() - l = screen.desktopLayout() - - rowstart = d - d % l.columns - target = d + num - while target >= rowstart + l.columns: - target -= l.columns - change_desktop(data, target) - -def send_to_desktop(data, num): - """Sends a client to a specified desktop""" - if not data.client: return - data.client.setDesktop(num) - -def toggle_all_desktops(data): - """Toggles between sending a client to all desktops and to the current - desktop.""" - if not data.client: return - if not data.client.desktop() == 0xffffffff: - send_to_desktop(data, 0xffffffff) - else: - send_to_desktop(data, ob.openbox.screen(data.screen).desktop()) - -def send_to_all_desktops(data): - """Sends a client to all desktops""" - if not data.client: return - send_to_desktop(data, 0xffffffff) - -def send_to_next_desktop(data, no_wrap=0, follow=1): - """Sends a window to the next desktop, optionally (by default) cycling - around to the first when going past the last. Also optionally moving to - the new desktop after sending the window.""" - if not data.client: return - screen = ob.openbox.screen(data.screen) - d = screen.desktop() - n = screen.numDesktops() - if (d < (n-1)): - d = d + 1 - elif not no_wrap: - d = 0 - send_to_desktop(data, d) - if follow: - change_desktop(data, d) - -def send_to_prev_desktop(data, no_wrap=0, follow=1): - """Sends a window to the previous desktop, optionally (by default) cycling - around to the last when going past the first. Also optionally moving to - the new desktop after sending the window.""" - if not data.client: return - screen = ob.openbox.screen(data.screen) - d = screen.desktop() - n = screen.numDesktops() - if (d > 0): - d = d - 1 - elif not no_wrap: - d = n - 1 - send_to_desktop(data, d) - if follow: - change_desktop(data, d) - -def restart(data=0, other = ""): - """Restarts Openbox, optionally starting another window manager.""" - ob.openbox.restart(other) - -def exit(data=0): - """Exits Openbox.""" - ob.openbox.shutdown() - -export_functions = iconify, restore, close, focus, raise_win, lower_win, \ - toggle_maximize, toggle_maximize_horz, \ - toggle_maximize_vert, maximize, maximize_horz, \ - maximize_vert, unmaximize, unmaximize_horz, \ - unmaximize_vert, toggle_shade, shade, unshade, \ - change_desktop, show_desktop, hide_desktop, \ - toggle_show_desktop, next_desktop, prev_desktop, \ - up_desktop, down_desktop, left_desktop, right_desktop, \ - send_to_desktop, toggle_all_desktops, send_to_all_desktops,\ - send_to_next_desktop, send_to_prev_desktop, restart, exit - -print "Loaded callbacks.py" diff --git a/scripts/config.py b/scripts/config.py deleted file mode 100644 index 97a45596..00000000 --- a/scripts/config.py +++ /dev/null @@ -1,244 +0,0 @@ -# Openbox's config system. Please use the defined functions instead of -# accessing the internal data structures directly, for the sake of us all. - -import ob - -def add(modulename, name, friendlyname, description, type, default, - **keywords): - """Add a variable to the configuration system. - - Add a variable to the configuration system for a module. - modulename - The name of the module, e.g. 'focus' - name - The name of the variable, e.g. 'my_variable' - friendlyname - The user-friendly name of the variable, e.g. 'My Variable' - description - The detailed destription of the variable, e.g. 'Does Things' - type - The type of the variable, one of: - - 'boolean' - - 'enum' - - 'integer' - - 'string' - - 'file' - - 'function' - - 'object' - default - The default value for the variable, e.g. 300 - keywords - Extra keyword=value pairs to further define the variable. These - can be: - - For 'enum' types: - - options : A list of possible options for the variable. - This *must* be set for all enum variables. - - For 'integer' types: - - min : The minimum value for the variable. - - max : The maximum value for the variable. - """ - modulename = str(modulename).lower() - name = str(name).lower() - friendlyname = str(friendlyname) - description = str(description) - type = str(type).lower() - - # make sure the sub-dicts exist - try: - _settings[modulename] - try: - _settings[modulename][name] - except KeyError: - _settings[modulename][name] = {} - except KeyError: - _settings[modulename] = {} - _settings[modulename][name] = {} - - # add the keywords first as they are used for the tests in set() - for key,value in zip(keywords.keys(), keywords.values()): - _settings[modulename][name][key] = value - - _settings[modulename][name]['name'] = friendlyname - _settings[modulename][name]['description'] = description - _settings[modulename][name]['type'] = type - _settings[modulename][name]['default'] = default - - # put it through the tests - try: - set(modulename, name, default) - except: - del _settings[modulename][name] - import sys - raise sys.exc_info()[0], sys.exc_info()[1] # re-raise it - -def set(modulename, name, value): - """Set a variable's value. - - Sets the value for a variable of the specified module. - modulename - The name of the module, e.g. 'focus' - name - The name of the variable, e.g. 'my_variable' - value - The new value for the variable. - """ - modulename = str(modulename).lower() - name = str(name).lower() - - # proper value checking for 'boolean's - if _settings[modulename][name]['type'] == 'boolean': - if not (value == 0 or value == 1): - raise ValueError, 'Attempted to set ' + name + ' to a value of '+\ - str(value) + ' but boolean variables can only contain 0 or'+\ - ' 1.' - - # proper value checking for 'enum's - elif _settings[modulename][name]['type'] == 'enum': - options = _settings[modulename][name]['options'] - if not value in options: - raise ValueError, 'Attempted to set ' + name + ' to a value of '+\ - str(value) + ' but this is not one of the possible values '+\ - 'for this enum variable. Possible values are: ' +\ - str(options) + "." - - # min/max checking for 'integer's - elif _settings[modulename][name]['type'] == 'integer': - try: - min = _settings[modulename][name]['min'] - if value < min: - raise ValueError, 'Attempted to set ' + name + ' to a value '+\ - ' of ' + str(value) + ' but it has a minimum value ' +\ - ' of ' + str(min) + '.' - except KeyError: pass - try: - max = _settings[modulename][name]['max'] - if value > max: - raise ValueError, 'Attempted to set ' + name + ' to a value '+\ - ' of ' + str(value) + ' but it has a maximum value ' +\ - ' of ' + str(min) + '.' - except KeyError: pass - - _settings[modulename][name]['value'] = value - -def reset(modulename, name): - """Reset a variable to its default value. - - Resets the value for a variable in the specified module back to its - original (default) value. - modulename - The name of the module, e.g. 'focus' - name - The name of the variable, e.g. 'my_variable' - """ - modulename = str(modulename).lower() - name = str(name).lower() - _settings[modulename][name]['value'] = \ - _settings[modulename][name]['default'] - -def get(modulename, name): - """Returns the value of a variable. - - Returns the current value for a variable in the specified module. - modulename - The name of the module, e.g. 'focus' - name - The name of the variable, e.g. 'my variable' - """ - modulename = str(modulename).lower() - name = str(name).lower() - return _settings[modulename][name]['value'] - -#---------------------------- Internals --------------------------- - -"""The main configuration dictionary, which holds sub-dictionaries for each - module. - - The format for entries in here like this (for a string): - _settings['modulename']['varname']['name'] = 'Text Label' - _settings['modulename']['varname']['description'] = 'Does this' - _settings['modulename']['varname']['type'] = 'string' - _settings['modulename']['varname']['default'] = 'Foo' - _settings['modulename']['varname']['value'] = 'Foo' - # 'value' should always be initialized to the same - # value as the 'default' field! - - Here's an example of an enum: - _settings['modulename']['varname']['name'] = 'My Enum Variable' - _settings['modulename']['varname']['description'] = 'Does Enum-like things.' - _settings['modulename']['varname']['type'] = 'enum' - _settings['modulename']['varname']['default'] = \ - _settings['modulename']['varname']['value'] = [ 'Blue', 'Green', 'Pink' ] - - And Here's an example of an integer with bounds: - _settings['modulename']['varname']['name'] = 'A Bounded Integer' - _settings['modulename']['varname']['description'] = 'A fierce party animal!' - _settings['modulename']['varname']['type'] = 'integer' - _settings['modulename']['varname']['default'] = \ - _settings['modulename']['varname']['value'] = 0 - _settings['modulename']['varname']['min'] = 0 - _settings['modulename']['varname']['max'] = 49 - - Hopefully you get the idea. - """ -_settings = {} - -"""Valid values for a variable's type.""" -_types = [ 'boolean', # Boolean types can only hold a value of 0 or 1. - - 'enum', # Enum types hold a value from a list of possible values. - # An 'options' field *must* be provided for enums, - # containing a list of possible values for the variable. - - 'integer', # Integer types hold a single number, as well as a 'min' - # and 'max' property. - # If the 'min' or 'max' is ignore then bounds checking - # will not be performed in that direction. - - 'string', # String types hold a text string. - - 'file', # File types hold a file object. - - 'function',# Function types hold any callable object. - - 'object' # Object types can hold any python object. - ]; - - - - - - - - - - - - - - - - - -############################################################################# -### Options that can be changed to adjust the behavior of Openbox. ### -############################################################################# - -THEME = "/usr/local/share/openbox/styles/fieron2" -"""The theme used to decorate everything.""" - -#TITLEBAR_LAYOUT = [ "icon", "title", "alldesktops", "iconify", "maximize", "close" ] -TITLEBAR_LAYOUT = "DITMC" -"""The layout of the buttons/label on client titlebars, can be made up of the -following: - I - iconify button - L - text label - M - maximize button, - D - all-desktops button - C - close button -If no 'L' is included in the string, one will be added to the end by -Openbox.""" - -DOUBLE_CLICK_DELAY = 300 -"""The number of milliseconds in which 2 clicks are perceived as a -double-click.""" - -DRAG_THRESHOLD = 3 -"""The amount of pixels that you have to drag the mouse before motion events -will start occuring.""" - -DESKTOP_NAMES = ["one", "two", "three", "four", "five", "six", "seven", \ - "eight", "nine", "ten", "eleven", "twelve"] -"""The name of each desktop.""" - -NUMBER_OF_DESKTOPS = 4 -"""The number of desktops/workspaces which can be scrolled between.""" - -############################################################################# - -print "Loaded config.py" diff --git a/scripts/cycle.py b/scripts/cycle.py deleted file mode 100644 index f77f3d8a..00000000 --- a/scripts/cycle.py +++ /dev/null @@ -1,473 +0,0 @@ -import ob, otk, config -class _Cycle: - """ - This is a basic cycling class for anything, from xOr's stackedcycle.py, - that pops up a cycling menu when there's more than one thing to be cycled - to. - An example of inheriting from and modifying this class is _CycleWindows, - which allows users to cycle around windows. - - This class could conceivably be used to cycle through anything -- desktops, - windows of a specific class, XMMS playlists, etc. - """ - - """This specifies a rough limit of characters for the cycling list titles. - Titles which are larger will be chopped with an elipsis in their - center.""" - TITLE_SIZE_LIMIT = 80 - - """If this is non-zero then windows will be activated as they are - highlighted in the cycling list (except iconified windows).""" - ACTIVATE_WHILE_CYCLING = 0 - - """If this is true, we start cycling with the next (or previous) thing - selected.""" - START_WITH_NEXT = 1 - - """If this is true, a popup window will be displayed with the options - while cycling.""" - SHOW_POPUP = 1 - - def __init__(self): - """Initialize an instance of this class. Subclasses should - do any necessary event binding in their constructor as well. - """ - self.cycling = 0 # internal var used for going through the menu - self.items = [] # items to cycle through - - self.widget = None # the otk menu widget - self.menuwidgets = [] # labels in the otk menu widget TODO: RENAME - - def createPopup(self): - """Creates the cycling popup menu. - """ - self.widget = otk.Widget(self.screen.number(), ob.openbox, - otk.Widget.Vertical, 0, 1) - - def destroyPopup(self): - """Destroys (or rather, cleans up after) the cycling popup menu. - """ - self.menuwidgets = [] - self.widget = 0 - - def populateItems(self): - """Populate self.items with the appropriate items that can currently - be cycled through. self.items may be cleared out before this - method is called. - """ - pass - - def menuLabel(self, item): - """Return a string indicating the menu label for the given item. - Don't worry about title truncation. - """ - pass - - def itemEqual(self, item1, item2): - """Compare two items, return 1 if they're "equal" for purposes of - cycling, and 0 otherwise. - """ - # suggestion: define __eq__ on item classes so that this works - # in the general case. :) - return item1 == item2 - - def populateLists(self): - """Populates self.items and self.menuwidgets, and then shows and - positions the cycling popup. You probably shouldn't mess with - this function; instead, see populateItems and menuLabel. - """ - self.widget.hide() - - try: - current = self.items[self.menupos] - except IndexError: - current = None - oldpos = self.menupos - self.menupos = -1 - - self.items = [] - self.populateItems() - - # make the widgets - i = 0 - self.menuwidgets = [] - for i in range(len(self.items)): - c = self.items[i] - - w = otk.Label(self.widget) - # current item might have shifted after a populateItems() - # call, so we need to do this test. - if current and self.itemEqual(c, current): - self.menupos = i - w.setHilighted(1) - self.menuwidgets.append(w) - - t = self.menuLabel(c) - # TODO: maybe subclasses will want to truncate in different ways? - if len(t) > self.TITLE_SIZE_LIMIT: # limit the length of titles - t = t[:self.TITLE_SIZE_LIMIT / 2 - 2] + "..." + \ - t[0 - self.TITLE_SIZE_LIMIT / 2 - 2:] - w.setText(t) - - # The item we were on might be gone entirely - if self.menupos < 0: - # try stay at the same spot in the menu - if oldpos >= len(self.items): - self.menupos = len(self.items) - 1 - else: - self.menupos = oldpos - - # find the size for the popup - width = 0 - height = 0 - for w in self.menuwidgets: - size = w.minSize() - if size.width() > width: width = size.width() - height += size.height() - - # show or hide the list and its child widgets - if len(self.items) > 1: - size = self.screen.size() - self.widget.moveresize(otk.Rect((size.width() - width) / 2, - (size.height() - height) / 2, - width, height)) - if self.SHOW_POPUP: self.widget.show(1) - - def activateTarget(self, final): - """Activates (focuses and, if the user requested it, raises a window). - If final is true, then this is the very last window we're activating - and the user has finished cycling. - """ - pass - - def setDataInfo(self, data): - """Retrieve and/or calculate information when we start cycling, - preferably caching it. Data is what's given to callback functions. - """ - self.screen = ob.openbox.screen(data.screen) - - def chooseStartPos(self): - """Set self.menupos to a number between 0 and len(self.items) - 1. - By default the initial menupos is 0, but this can be used to change - it to some other position.""" - pass - - def cycle(self, data, forward): - """Does the actual job of cycling through windows. data is a callback - parameter, while forward is a boolean indicating whether the - cycling goes forwards (true) or backwards (false). - """ - - initial = 0 - - if not self.cycling: - ob.kgrab(data.screen, self.grabfunc) - # 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) - - self.cycling = 1 - self.state = data.state - self.menupos = 0 - - self.setDataInfo(data) - - self.createPopup() - self.items = [] # so it doesnt try start partway through the list - self.populateLists() - - self.chooseStartPos() - self.initpos = self.menupos - - initial = 1 - - if not self.items: return # don't bother doing anything - - self.menuwidgets[self.menupos].setHighlighted(0) - - if initial and not self.START_WITH_NEXT: - pass - else: - if forward: - self.menupos += 1 - else: - self.menupos -= 1 - # wrap around - if self.menupos < 0: self.menupos = len(self.items) - 1 - elif self.menupos >= len(self.items): self.menupos = 0 - self.menuwidgets[self.menupos].setHighlighted(1) - if self.ACTIVATE_WHILE_CYCLING: - self.activateTarget(0) # activate, but dont deiconify/unshade/raise - - def grabfunc(self, data): - """A callback method that grabs away all keystrokes so that navigating - the cycling menu is possible.""" - done = 0 - notreverting = 1 - # have all the modifiers this started with been released? - if not self.state & data.state: - done = 1 - elif data.action == ob.KeyAction.Press: - # has Escape been pressed? - if data.key == "Escape": - done = 1 - notreverting = 0 - # revert - self.menupos = self.initpos - # has Enter been pressed? - elif data.key == "Return": - done = 1 - - if done: - # activate, and deiconify/unshade/raise - self.activateTarget(notreverting) - self.destroyPopup() - self.cycling = 0 - ob.kungrab() - ob.mungrab() - - def next(self, data): - """Focus the next window.""" - self.cycle(data, 1) - - def previous(self, data): - """Focus the previous window.""" - self.cycle(data, 0) - -#---------------------- Window Cycling -------------------- -import focus -class _CycleWindows(_Cycle): - """ - This is a basic cycling class for Windows. - - An example of inheriting from and modifying this class is - _ClassCycleWindows, which allows users to cycle around windows of a certain - application name/class only. - - This class has an underscored name because I use the singleton pattern - (so CycleWindows is an actual instance of this class). This doesn't have - to be followed, but if it isn't followed then the user will have to create - their own instances of your class and use that (not always a bad thing). - - An example of using the CycleWindows singleton: - - from cycle import CycleWindows - CycleWindows.INCLUDE_ICONS = 0 # I don't like cycling to icons - ob.kbind(["A-Tab"], ob.KeyContext.All, CycleWindows.next) - ob.kbind(["A-S-Tab"], ob.KeyContext.All, CycleWindows.previous) - """ - - """If this is non-zero then windows from all desktops will be included in - the stacking list.""" - INCLUDE_ALL_DESKTOPS = 0 - - """If this is non-zero then windows which are iconified on the current - desktop will be included in the stacking list.""" - INCLUDE_ICONS = 1 - - """If this is non-zero then windows which are iconified from all desktops - will be included in the stacking list.""" - INCLUDE_ICONS_ALL_DESKTOPS = 1 - - """If this is non-zero then windows which are on all-desktops at once will - be included.""" - INCLUDE_OMNIPRESENT = 1 - - """A better default for window cycling than generic cycling.""" - ACTIVATE_WHILE_CYCLING = 1 - - """When cycling focus, raise the window chosen as well as focusing it.""" - RAISE_WINDOW = 1 - - def __init__(self): - _Cycle.__init__(self) - - def newwindow(data): - if self.cycling: self.populateLists() - def closewindow(data): - if self.cycling: self.populateLists() - - ob.ebind(ob.EventAction.NewWindow, newwindow) - ob.ebind(ob.EventAction.CloseWindow, closewindow) - - def shouldAdd(self, client): - """Determines if a client should be added to the cycling list.""" - curdesk = self.screen.desktop() - desk = client.desktop() - - if not client.normal(): return 0 - if not (client.canFocus() or client.focusNotify()): return 0 - if config.get('focus', 'avoid_skip_taskbar') and client.skipTaskbar(): - return 0 - - if client.iconic(): - if self.INCLUDE_ICONS: - if self.INCLUDE_ICONS_ALL_DESKTOPS: return 1 - if desk == curdesk: return 1 - return 0 - if self.INCLUDE_OMNIPRESENT and desk == 0xffffffff: return 1 - if self.INCLUDE_ALL_DESKTOPS: return 1 - if desk == curdesk: return 1 - - return 0 - - def populateItems(self): - # get the list of clients, keeping iconic windows at the bottom - iconic_clients = [] - for c in focus._clients: - if self.shouldAdd(c): - if c.iconic(): iconic_clients.append(c) - else: self.items.append(c) - self.items.extend(iconic_clients) - - def menuLabel(self, client): - if client.iconic(): t = '[' + client.iconTitle() + ']' - else: t = client.title() - - if self.INCLUDE_ALL_DESKTOPS: - d = client.desktop() - if d == 0xffffffff: d = self.screen.desktop() - t = self.screen.desktopNames()[d] + " - " + t - - return t - - def itemEqual(self, client1, client2): - return client1.window() == client2.window() - - def activateTarget(self, final): - """Activates (focuses and, if the user requested it, raises a window). - If final is true, then this is the very last window we're activating - and the user has finished cycling.""" - try: - client = self.items[self.menupos] - except IndexError: return # empty list - - # move the to client's desktop if required - if not (client.iconic() or client.desktop() == 0xffffffff or \ - client.desktop() == self.screen.desktop()): - self.screen.changeDesktop(client.desktop()) - - # send a net_active_window message for the target - if final or not client.iconic(): - if final: r = self.RAISE_WINDOW - else: r = 0 - client.focus(final, r) - if not final: - focus._skip += 1 - -# The singleton. -CycleWindows = _CycleWindows() - -#---------------------- Window Cycling -------------------- -import focus -class _CycleWindowsLinear(_CycleWindows): - """ - This class is an example of how to inherit from and make use of the - _CycleWindows class. This class also uses the singleton pattern. - - An example of using the CycleWindowsLinear singleton: - - from cycle import CycleWindowsLinear - CycleWindows.ALL_DESKTOPS = 1 # I want all my windows in the list - ob.kbind(["A-Tab"], ob.KeyContext.All, CycleWindowsLinear.next) - ob.kbind(["A-S-Tab"], ob.KeyContext.All, CycleWindowsLinear.previous) - """ - - """When cycling focus, raise the window chosen as well as focusing it.""" - RAISE_WINDOW = 0 - - """If this is true, a popup window will be displayed with the options - while cycling.""" - SHOW_POPUP = 0 - - def __init__(self): - _CycleWindows.__init__(self) - - def shouldAdd(self, client): - """Determines if a client should be added to the cycling list.""" - curdesk = self.screen.desktop() - desk = client.desktop() - - if not client.normal(): return 0 - if not (client.canFocus() or client.focusNotify()): return 0 - if config.get('focus', 'avoid_skip_taskbar') and client.skipTaskbar(): - return 0 - - if client.iconic(): return 0 - if self.INCLUDE_OMNIPRESENT and desk == 0xffffffff: return 1 - if self.INCLUDE_ALL_DESKTOPS: return 1 - if desk == curdesk: return 1 - - return 0 - - def populateItems(self): - # get the list of clients, keeping iconic windows at the bottom - iconic_clients = [] - for c in self.screen.clients: - if self.shouldAdd(c): - self.items.append(c) - - def chooseStartPos(self): - if focus._clients: - t = focus._clients[0] - for i,c in zip(range(len(self.items)), self.items): - if self.itemEqual(c, t): - self.menupos = i - break - - def menuLabel(self, client): - t = client.title() - - if self.INCLUDE_ALL_DESKTOPS: - d = client.desktop() - if d == 0xffffffff: d = self.screen.desktop() - t = self.screen.desktopNames()[d] + " - " + t - - return t - -# The singleton. -CycleWindowsLinear = _CycleWindowsLinear() - -#----------------------- Desktop Cycling ------------------ -class _CycleDesktops(_Cycle): - """ - Example of usage: - - from cycle import CycleDesktops - ob.kbind(["W-d"], ob.KeyContext.All, CycleDesktops.next) - ob.kbind(["W-S-d"], ob.KeyContext.All, CycleDesktops.previous) - """ - class Desktop: - def __init__(self, name, index): - self.name = name - self.index = index - def __eq__(self, other): - return other.index == self.index - - def __init__(self): - _Cycle.__init__(self) - - def populateItems(self): - names = self.screen.desktopNames() - num = self.screen.numDesktops() - for n, i in zip(names[:num], range(num)): - self.items.append(_CycleDesktops.Desktop(n, i)) - - def menuLabel(self, desktop): - return desktop.name - - def chooseStartPos(self): - self.menupos = self.screen.desktop() - - def activateTarget(self, final): - # TODO: refactor this bit - try: - desktop = self.items[self.menupos] - except IndexError: return - - self.screen.changeDesktop(desktop.index) - -CycleDesktops = _CycleDesktops() - -print "Loaded cycle.py" diff --git a/scripts/defaults.py b/scripts/defaults.py deleted file mode 100644 index 459c0d61..00000000 --- a/scripts/defaults.py +++ /dev/null @@ -1,78 +0,0 @@ -import ob # base module -import focus # add some default focus handling and cycling functions -import focusmodel # default focus models -import behavior # defines default behaviors for interaction with windows -import callbacks # a lib of functions that can be used as binding callbacks -import windowplacement # use a routine in here to place windows -import historyplacement # history window placement - -# try focus something when nothing is focused -focus.FALLBACK = 1 - -# choose a default focus model -focusmodel.setup_click_focus() # use focusmodel.setup_sloppy_focus() instead to - # make focus follow the cursor, or bind things - # in some way like these functions do to make - # your own custom focus model. -# set up the mouse buttons -behavior.setup_window_clicks() -behavior.setup_window_buttons() -behavior.setup_scroll() - -# my window placement algorithm -#ob.ebind(ob.EventAction.PlaceWindow, windowplacement.random) -ob.ebind(ob.EventAction.PlaceWindow, historyplacement.place) -# don't place terminals by history placement (xterm,aterm,rxvt) -def histplace(data): - if data.client.appClass() == "XTerm": return 0 - return 1 -historyplacement.CONFIRM_CALLBACK = histplace - - -# run xterm from root clicks -ob.mbind("Left", ob.MouseContext.Root, ob.MouseAction.Click, - lambda(d): ob.execute("xterm", d.screen)) - -ob.kbind(["A-F4"], ob.KeyContext.All, callbacks.close) - -ob.kbind(["W-d"], ob.KeyContext.All, callbacks.toggle_show_desktop) - -# focus bindings - -from cycle import CycleWindows -ob.kbind(["A-Tab"], ob.KeyContext.All, CycleWindows.next) -ob.kbind(["A-S-Tab"], ob.KeyContext.All, CycleWindows.previous) - -# if you want linear cycling instead of stacked cycling, comment out the two -# bindings above, and use these instead. -#from cycle import CycleWindowsLinear -#ob.kbind(["A-Tab"], ob.KeyContext.All, CycleWindows.next) -#ob.kbind(["A-S-Tab"], ob.KeyContext.All, CycleWindows.previous) - -from cycle import CycleDesktops -ob.kbind(["C-Tab"], ob.KeyContext.All, CycleDesktops.next) -ob.kbind(["C-S-Tab"], ob.KeyContext.All, CycleDesktops.previous) - -# desktop changing bindings -ob.kbind(["C-1"], ob.KeyContext.All, lambda(d): callbacks.change_desktop(d, 0)) -ob.kbind(["C-2"], ob.KeyContext.All, lambda(d): callbacks.change_desktop(d, 1)) -ob.kbind(["C-3"], ob.KeyContext.All, lambda(d): callbacks.change_desktop(d, 2)) -ob.kbind(["C-4"], ob.KeyContext.All, lambda(d): callbacks.change_desktop(d, 3)) -ob.kbind(["C-A-Right"], ob.KeyContext.All, - lambda(d): callbacks.right_desktop(d)) -ob.kbind(["C-A-Left"], ob.KeyContext.All, - lambda(d): callbacks.left_desktop(d)) -ob.kbind(["C-A-Up"], ob.KeyContext.All, - lambda(d): callbacks.up_desktop(d)) -ob.kbind(["C-A-Down"], ob.KeyContext.All, - lambda(d): callbacks.down_desktop(d)) - -ob.kbind(["C-S-A-Right"], ob.KeyContext.All, - lambda(d): callbacks.send_to_next_desktop(d)) -ob.kbind(["C-S-A-Left"], ob.KeyContext.All, - lambda(d): callbacks.send_to_prev_desktop(d)) - -# focus new windows -ob.ebind(ob.EventAction.NewWindow, callbacks.focus) - -print "Loaded defaults.py" diff --git a/scripts/focus.py b/scripts/focus.py deleted file mode 100644 index 9eb6bfb8..00000000 --- a/scripts/focus.py +++ /dev/null @@ -1,89 +0,0 @@ -########################################################################### -### Functions for helping out with your window focus. ### -########################################################################### - -import config, ob - -export_functions = () - -config.add('focus', - 'avoid_skip_taskbar', - 'Avoid SkipTaskbar Windows', - "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 'Focus Fallback' is enabled.", - 'boolean', - 1) - -config.add('focus', - 'fallback', - 'Focus Fallback', - "Send focus somewhere when nothing is left with the focus, if " + \ - "possible.", - 'boolean', - 1) - -# maintain a list of clients, stacked in focus order -_clients = [] -_skip = 0 - -def _focusable(client, desktop): - if not client.normal(): return 0 - if not (client.canFocus() or client.focusNotify()): return 0 - if client.iconic(): return 0 - if config.get('focus', 'avoid_skip_taskbar') and \ - client.skipTaskbar(): return 0 - - desk = client.desktop() - if not (desk == 0xffffffff or desk == desktop): return 0 - - return 1 - -def _remove(client): - """This function exists because Swig pointers don't define a __eq__ - function, so list.remove(ptr) does not work.""" - win = client.window() - for i in range(len(_clients)): - if _clients[i].window() == win: - _clients.pop(i) - return - raise ValueError("_remove(x): x not in _clients list.") - -def _focused(data): - global _clients, _skip - - if _skip: - _skip -= 1 - return - - if data.client: - # move it to the top - try: - _remove(data.client) - except ValueError: pass # happens if _focused comes before _newwindow - _clients.insert(0, data.client) - elif config.get('focus', 'fallback'): - # pass around focus - desktop = ob.openbox.screen(data.screen).desktop() - for c in _clients: - if _focusable(c, desktop): - c.focus() - break - -def _newwindow(data): - # make sure its not already in the list - win = data.client.window() - for i in range(len(_clients)): - if _clients[i].window() == win: - return - _clients.append(data.client) - -def _closewindow(data): - _remove(data.client) - -ob.ebind(ob.EventAction.NewWindow, _newwindow) -ob.ebind(ob.EventAction.CloseWindow, _closewindow) -ob.ebind(ob.EventAction.Focus, _focused) - -print "Loaded focus.py" diff --git a/scripts/focusmodel.py b/scripts/focusmodel.py deleted file mode 100644 index a0b6c927..00000000 --- a/scripts/focusmodel.py +++ /dev/null @@ -1,61 +0,0 @@ -############################################################################### -### Functions for setting up some default focus models. ### -############################################################################### - -import ob -import callbacks - -def setup_click_focus(click_raise = 1): - """Sets up for focusing windows by clicking on or in the window. - Optionally, clicking on or in a window can raise the window to the - front of its stacking layer.""" - ob.mbind("Left", ob.MouseContext.Titlebar, - ob.MouseAction.Press, callbacks.focus) - ob.mbind("Left", ob.MouseContext.Handle, - ob.MouseAction.Press, callbacks.focus) - ob.mbind("Left", ob.MouseContext.Grip, - ob.MouseAction.Press, callbacks.focus) - ob.mbind("Left", ob.MouseContext.Window, - ob.MouseAction.Press, callbacks.focus) - ob.mbind("Middle", ob.MouseContext.Window, - ob.MouseAction.Press, callbacks.focus) - ob.mbind("A-Left", ob.MouseContext.Frame, - ob.MouseAction.Press, callbacks.focus) - if click_raise: - ob.mbind("Left", ob.MouseContext.Titlebar, - ob.MouseAction.Press, callbacks.raise_win) - ob.mbind("Left", ob.MouseContext.Handle, - ob.MouseAction.Press, callbacks.raise_win) - ob.mbind("Left", ob.MouseContext.Grip, - ob.MouseAction.Press, callbacks.raise_win) - ob.mbind("Left", ob.MouseContext.Window, - ob.MouseAction.Press, callbacks.raise_win) - -def setup_sloppy_focus(click_focus = 1, click_raise = 0): - """Sets up for focusing windows when the mouse pointer enters them. - Optionally, clicking on or in a window can focus it if your pointer - ends up inside a window without focus. Also, optionally, clicking on or - in a window can raise the window to the front of its stacking layer.""" - ob.ebind(ob.EventAction.EnterWindow, callbacks.focus) - if click_focus: - ob.mbind("Left", ob.MouseContext.Titlebar, - ob.MouseAction.Press, callbacks.focus) - ob.mbind("Left", ob.MouseContext.Handle, - ob.MouseAction.Press, callbacks.focus) - ob.mbind("Left", ob.MouseContext.Grip, - ob.MouseAction.Press, callbacks.focus) - ob.mbind("Left", ob.MouseContext.Window, - ob.MouseAction.Press, callbacks.focus) - if click_raise: - ob.mbind("Left", ob.MouseContext.Titlebar, - ob.MouseAction.Press, callbacks.raise_win) - ob.mbind("Left", ob.MouseContext.Handle, - ob.MouseAction.Press, callbacks.raise_win) - ob.mbind("Left", ob.MouseContext.Grip, - ob.MouseAction.Press, callbacks.raise_win) - ob.mbind("Left", ob.MouseContext.Window, - ob.MouseAction.Press, callbacks.raise_win) - -export_functions = setup_click_focus, setup_sloppy_focus - -print "Loaded focusmodel.py" diff --git a/scripts/historyplacement.py b/scripts/historyplacement.py deleted file mode 100644 index fb1dd35b..00000000 --- a/scripts/historyplacement.py +++ /dev/null @@ -1,185 +0,0 @@ -############################################################################## -### The history window placement algorithm. ebind historyplacement.place ### -### to the ob.EventAction.PlaceWindow event to use it. ### -############################################################################## - -import windowplacement, config - -def place(data): - """Place a window usingthe history placement algorithm.""" - _place(data) - -export_functions = place - -############################################################################## - -config.add('historyplacement', - 'ignore_requested_positions', - 'Ignore Requested Positions', - "When true, the placement algorithm will attempt to place " + \ - "windows even when they request a position (like XMMS can)." + \ - "Note this only applies to 'normal' windows, not to special " + \ - "cases like desktops and docks.", - 'boolean', - 0) -config.add('historyplacement', - 'dont_duplicate', - "Don't Diplicate", - "When true, if 2 copies of the same match in history are to be " + \ - "placed before one of them is closed (so it would be placed " + \ - "over-top of the last one), this will cause the second window to "+\ - "not be placed via history, and the 'Fallback Algorithm' will be "+\ - "used instead.", - 'boolean', - 1) -config.add('historyplacement', - 'filename', - 'History Database Filename', - "The name of the file where history data will be stored. The " + \ - "number of the screen is appended onto this name. The file will " +\ - "be placed in ~/.openbox/.", - 'string', - 'historydb') -config.add('historyplacement', - 'fallback', - 'Fallback Algorithm', - "The window placement algorithm that will be used when history " + \ - "placement does not have a place for the window.", - 'enum', - windowplacement.random, - options = windowplacement.export_functions) - -########################################################################### - -########################################################################### -### Internal stuff, should not be accessed outside the module. ### -########################################################################### - -import otk -import ob -import os -import string - -_data = [] - -class _state: - def __init__(self, appname, appclass, role, x, y): - self.appname = appname - self.appclass = appclass - self.role = role - self.x = x - self.y = y - self.placed = 0 - def __eq__(self, other): - if self.appname == other.appname and \ - self.appclass == other.appclass and \ - self.role == other.role: - return 1 - return 0 - -def _load(data): - global _data - try: - file = open(os.environ['HOME'] + '/.openbox/' + \ - config.get('historyplacement', 'filename') + \ - "." + str(data.screen), 'r') - # read data - for line in file.readlines(): - line = line[:-1] # drop the '\n' - try: - s = string.split(line, '\0') - state = _state(s[0], s[1], s[2], - string.atoi(s[3]), string.atoi(s[4])) - - while len(_data)-1 < data.screen: - _data.append([]) - _data[data.screen].append(state) - - except ValueError: pass - except IndexError: pass - file.close() - except IOError: pass - -def _save(data): - global _data - file = open(os.environ['HOME']+'/.openbox/'+ \ - config.get('historyplacement', 'filename') + \ - "." + str(data.screen), 'w') - if file: - while len(_data)-1 < data.screen: - _data.append([]) - for i in _data[data.screen]: - file.write(i.appname + '\0' + - i.appclass + '\0' + - i.role + '\0' + - str(i.x) + '\0' + - str(i.y) + '\n') - file.close() - -def _create_state(data): - global _data - area = data.client.area() - return _state(data.client.appName(), data.client.appClass(), - data.client.role(), area.x(), area.y()) - -def _find(screen, state): - global _data - try: - return _data[screen].index(state) - except ValueError: - return -1 - except IndexError: - while len(_data)-1 < screen: - _data.append([]) - return _find(screen, state) # try again - -def _place(data): - global _data - if data.client: - if not (config.get('historyplacement', 'ignore_requested_positions') \ - and data.client.normal()): - if data.client.positionRequested(): return - state = _create_state(data) - try: - print "looking for : " + state.appname + " : " + \ - state.appclass + " : " + state.role - - i = _find(data.screen, state) - if i >= 0: - coords = _data[data.screen][i] - print "Found in history ("+str(coords.x)+","+\ - str(coords.y)+")" - if not (config.get('historyplacement', 'dont_duplicate') \ - and coords.placed): - data.client.move(coords.x, coords.y) - coords.placed = 1 - return - else: - print "Already placed another window there" - else: - print "No match in history" - except TypeError: - pass - fallback = config.get('historyplacement', 'fallback') - if fallback: fallback(data) - -def _save_window(data): - global _data - if data.client: - state = _create_state(data) - print "looking for : " + state.appname + " : " + state.appclass + \ - " : " + state.role - - i = _find(data.screen, state) - if i >= 0: - print "replacing" - _data[data.screen][i] = state # replace it - else: - print "appending" - _data[data.screen].append(state) - -ob.ebind(ob.EventAction.CloseWindow, _save_window) -ob.ebind(ob.EventAction.Startup, _load) -ob.ebind(ob.EventAction.Shutdown, _save) - -print "Loaded historyplacement.py" diff --git a/scripts/motion.py b/scripts/motion.py deleted file mode 100644 index e25604e5..00000000 --- a/scripts/motion.py +++ /dev/null @@ -1,348 +0,0 @@ -############################################################################ -### Functions that provide callbacks for motion events to move and ### -### resize windows. ### -############################################################################ - -def move(data): - """Moves the window interactively. This should only be used with - MouseAction.Motion events. If 'Coords Popup for Moving' or 'Rubberband - Mode for Moving' is enabled, then the end_move function needs to be - bound as well.""" - _move(data) - -def end_move(data): - """Complete the interactive move of a window.""" - _end_move(data) - -def resize(data): - """Resizes the window interactively. This should only be used with - MouseMotion events. If 'Coords Popup for Resizing' or 'Rubberband Mode - for Resizing' is enabled, then the end_resize function needs to be - bound as well.""" - _resize(data) - -def end_resize(data): - """Complete the interactive resize of a window.""" - _end_resize(data) - -export_functions = move, end_move, resize, end_resize - -############################################################################# - -import config - -config.add('motion', - 'edge_resistance', - 'Edge Resistance', - "The amount of resistance to provide to moving a window past a " + \ - "screen boundary. Specify a value of 0 to disable edge resistance.", - 'integer', - 10, - min = 0) -config.add('motion', - 'popup_in_window', - 'Coords Popup In Window', - "When this is true, the coordinates popups will be placed " + \ - "relative to the window being moved/resized. When false, they " + \ - "will appear relative to the entire screen.", - 'boolean', - 0) -config.add('motion', - 'popup_centered', - 'Coords Popup Centered', - "When this is true, the coordinates popups will be centered " + \ - "relative to the window or screen (see 'Coords Popup In " + \ - "Window'). When false, they will be placed based upon the " + \ - "'Coords Popup Position' options.", - 'boolean', - 1) -config.add('motion', - 'popup_coords_x', - 'Coords Popup Position - X', - "When 'Coords Popup Centered' is false, this position will be " + \ - "used to place the coordinates popups. The popups will be " + \ - "placed relative to the window or the screen (see 'Coords " + \ - "Popup In Window'). A value of 0 would place it at the left " + \ - "edge, while a value of -1 would place it at the right edge. " + \ - "This value behaves similarly to those passed to the -geometry " + \ - "flag of many applications.", - 'integer', - 0) -config.add('motion', - 'popup_coords_y', - 'Coords Popup Position - Y', - "When 'Coords Popup Centered' is false, this position will be " + \ - "used to place the coordinates popups. The popups will be " + \ - "placed relative to the window or the screen (see 'Coords Popup " +\ - "In Window'). A value of 0 would place it at the top edge, " + \ - "while a value of -1 would place it at the bottom edge. This " + \ - "value behaves similarly to those passed to the -geometry flag " + \ - "of many applications.", - 'integer', - 0) -config.add('motion', - 'move_popup', - 'Coords Popup for Moving', - "Option to display a coordinates popup when moving windows.", - 'boolean', - 1) -config.add('motion', - 'move_rubberband', - 'Rubberband Mode for Moving', - "NOT IMPLEMENTED (yet?)\n"+\ - "Display an outline while moving instead of moving the actual " + \ - "window, until the move is completed. Good for slower systems.", - 'boolean', - 0) -config.add('motion', - 'resize_popup', - 'Coords Popup for Resizing', - "Option to display a coordinates popup when resizing windows.", - 'boolean', - 1) -config.add('motion', - 'resize_rubberband', - 'Rubberband Mode for Resizing', - "NOT IMPLEMENTED (yet?)\n"+\ - "Display an outline while resizing instead of resizing the " + \ - "actual window, until the resize is completed. Good for slower " + \ - "systems.", - 'boolean', - 0) -config.add('motion', - 'resize_nearest', - 'Resize Nearest Corner', - "When true, resizing will occur from the corner nearest where " + \ - "the mouse is. When false resizing will always occur from the " + \ - "bottom right corner.", - 'boolean', - 1) - -########################################################################### -### Internal stuff, should not be accessed outside the module. ### -########################################################################### - -import ob -import otk - -_popwidget = 0 - -# motion state -_inmove = 0 -_inresize = 0 - -# last motion data -_cx = 0 -_cy = 0 -_cw = 0 -_ch = 0 -_px = 0 -_py = 0 -_dx = 0 -_dy = 0 -_client = 0 -_screen = 0 - -_motion_mask = 0 - -def _place_popup(): - if config.get('motion', 'popup_in_window'): - # use the actual client's area, not the frame's - area = _client.frame.area() - size = _client.frame.size() - area = otk.Rect(area.x() + size.left, area.y() + size.top, - area.width() - size.left - size.right, - area.height() - size.top - size.bottom) - else: - area = otk.Rect(otk.Point(0, 0), ob.openbox.screen(_screen).size()) - size = _popwidget.minSize() - if config.get('motion', 'popup_centered'): - x = area.position().x() + (area.size().width() - size.width()) / 2 - y = area.position().y() + (area.size().height() - size.height()) / 2 - else: - x = config.get('motion', 'popup_coords_x') - y = config.get('motion', 'popup_coords_y') - if x < 0: x += area.width() - size.width() + 1 - if y < 0: y += area.width() - size.height() + 1 - x += area.position().x() - y += area.position().y() - _popwidget.moveresize(otk.Rect(x, y, size.width(), size.height())) - -def _motion_grab(data): - global _motion_mask, _inmove, _inresize; - - # are all the modifiers this started with still pressed? - if not _motion_mask & data.state: - if _inmove: - _end_move(data) - elif _inresize: - _end_resize(data) - else: - raise RuntimeError - -_last_x = 0 -_last_y = 0 - -def _do_move(final): - global _screen, _client, _cx, _cy, _dx, _dy - - # get destination x/y for the *frame* - x = _cx + _dx + _client.frame.area().x() - _client.area().x() - y = _cy + _dy + _client.frame.area().y() - _client.area().y() - - global _last_x, _last_y - resist = config.get('motion', 'edge_resistance') - if resist: - fs = _client.frame.size() - w = _client.area().width() + fs.left + fs.right - h = _client.area().height() + fs.top + fs.bottom - # use the area based on the struts - area = ob.openbox.screen(_screen).area(_client.desktop()) - l = area.left() - r = area.right() - w + 1 - t = area.top() - b = area.bottom() - h + 1 - # left screen edge - if _last_x > x and x < l and x >= l - resist: - x = l - # right screen edge - if _last_x < x and x > r and x <= r + resist: - x = r - # top screen edge - if _last_y > y and y < t and y >= t - resist: - y = t - # right screen edge - if _last_y < y and y > b and y <= b + resist: - y = b - - global _inmove - if not _inmove: - _last_x = 0 - _last_y = 0 - else: - _last_x = x - _last_y = y - - if not final and config.get('motion', 'move_rubberband'): - # XXX draw the outline ... - pass - else: - _client.move(x, y, final) - - if config.get('motion', 'move_popup'): - global _popwidget - text = "X: " + str(x) + " Y: " + str(y) - if not _popwidget: - _popwidget = otk.Label(_screen, ob.openbox) - _popwidget.setHighlighted(1) - _popwidget.setText(text) - _place_popup() - _popwidget.show() - -def _move(data): - if not data.client: return - - # not-normal windows dont get moved - if not data.client.normal(): return - - global _screen, _client, _cx, _cy, _dx, _dy, _motion_mask - _screen = data.screen - _client = data.client - _cx = data.press_clientx - _cy = data.press_clienty - _dx = data.xroot - data.pressx - _dy = data.yroot - data.pressy - _motion_mask = data.state - _do_move(0) - global _inmove - if not _inmove: - ob.kgrab(_screen, _motion_grab) - _inmove = 1 - -def _end_move(data): - global _inmove, _popwidget - if _inmove: - _do_move(1) - _inmove = 0 - _popwidget = 0 - ob.kungrab() - -def _do_resize(final): - global _screen, _client, _cx, _cy, _cw, _ch, _px, _py, _dx, _dy - - dx = _dx - dy = _dy - - # pick a corner to anchor - if not (config.get('motion', 'resize_nearest') or - _context == ob.MouseContext.Grip): - corner = ob.Client.TopLeft - else: - x = _px - _cx - y = _py - _cy - if y < _ch / 2: - if x < _cw / 2: - corner = ob.Client.BottomRight - dx *= -1 - else: - corner = ob.Client.BottomLeft - dy *= -1 - else: - if x < _cw / 2: - corner = ob.Client.TopRight - dx *= -1 - else: - corner = ob.Client.TopLeft - - w = _cw + dx - h = _ch + dy - - if not final and config.get('motion', 'resize_rubberband'): - # XXX draw the outline ... - pass - else: - _client.resize(corner, w, h) - - if config.get('motion', 'resize_popup'): - global _popwidget - ls = _client.logicalSize() - text = "W: " + str(ls.width()) + " H: " + str(ls.height()) - if not _popwidget: - _popwidget = otk.Label(_screen, ob.openbox) - _popwidget.setHighlighted(1) - _popwidget.setText(text) - _place_popup() - _popwidget.show() - -def _resize(data): - if not data.client: return - - # not-normal windows dont get resized - if not data.client.normal(): return - - global _screen, _client, _cx, _cy, _cw, _ch, _px, _py, _dx, _dy - global _motion_mask - _screen = data.screen - _client = data.client - _cx = data.press_clientx - _cy = data.press_clienty - _cw = data.press_clientwidth - _ch = data.press_clientheight - _px = data.pressx - _py = data.pressy - _dx = data.xroot - _px - _dy = data.yroot - _py - _motion_mask = data.state - _do_resize(0) - global _inresize - if not _inresize: - ob.kgrab(_screen, _motion_grab) - _inresize = 1 - -def _end_resize(data): - global _inresize, _popwidget - if _inresize: - _do_resize(1) - _inresize = 0 - _popwidget = 0 - ob.kungrab() diff --git a/scripts/windowplacement.py b/scripts/windowplacement.py deleted file mode 100644 index 505993c5..00000000 --- a/scripts/windowplacement.py +++ /dev/null @@ -1,50 +0,0 @@ -############################################################################ -### Window placement algorithms, choose one of these and ebind it to the ### -### ob.EventAction.PlaceWindow event. ### -### ### -### Also see historyplacement.py for the history placement module which ### -### provides an algorithm that can be used in place of, or alongside, ### -### these. ### -############################################################################ - -import otk, ob, random - -_rand = random.Random() - -def random(data): - """Place windows randomly around the screen.""" - if not data.client: return - if data.client.positionRequested(): return - client_area = data.client.frame.area() - screen_area = ob.openbox.screen(data.screen).area(data.client.desktop()) - width = screen_area.width() - client_area.width() - height = screen_area.height() - client_area.height() - global _rand - x = _rand.randrange(screen_area.x(), width-1) - y = _rand.randrange(screen_area.y(), height-1) - data.client.move(x, y) - -_cascade_x = 0 -_cascade_y = 0 - -def cascade(data): - """Place windows in a cascading order from top-left to bottom-right.""" - if not data.client: return - if data.client.positionRequested(): return - client_area = data.client.frame.area() - screen_area = ob.openbox.screen(data.screen).area(data.client.desktop()) - width = screen_area.width() - client_area.width() - height = screen_area.height() - client_area.height() - global _cascade_x, _cascade_y - if _cascade_x < screen_area.x() or _cascade_y < screen_area.y() or \ - _cascade_x >= width or _cascade_y >= height: - _cascade_x = screen_area.x() - _cascade_y = screen_area.y() - data.client.move(_cascade_x, _cascade_y) - frame_size = data.client.frame.size() - _cascade_x += frame_size.top - _cascade_y += frame_size.top - -export_functions = random, cascade - -print "Loaded windowplacement.py" |
