summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2003-03-21 18:42:39 +0000
committerDana Jansens <danakj@orodu.net>2003-03-21 18:42:39 +0000
commita52a6d96d701c993896f276e4198003317632aaf (patch)
treebe2f51e6a433d1fdf9a7c8248b343cb3f6297212 /scripts
parenta36c7543d4eedaa9e10bfd9f4d9b81279b1bb7e6 (diff)
rm the old code including the .pys and the c++ shit
Diffstat (limited to 'scripts')
-rw-r--r--scripts/.cvsignore2
-rw-r--r--scripts/Makefile.am10
-rw-r--r--scripts/behavior.py115
-rw-r--r--scripts/callbacks.py284
-rw-r--r--scripts/config.py244
-rw-r--r--scripts/cycle.py473
-rw-r--r--scripts/defaults.py78
-rw-r--r--scripts/focus.py89
-rw-r--r--scripts/focusmodel.py61
-rw-r--r--scripts/historyplacement.py185
-rw-r--r--scripts/motion.py348
-rw-r--r--scripts/windowplacement.py50
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"