import otk
StateRemove = 0
+"""For the state_* callbacks. Indicates the state should be removed from the
+ window."""
StateAdd = 1
+"""For the state_* callbacks. Indicates the state should be add to the
+ window."""
StateToggle = 2
+"""For the state_* callbacks. Indicates the state should be toggled on the
+ window."""
def state_above(data, add=StateAdd):
"""Toggles, adds or removes the 'above' state on a window.
#############################################################################
-### Options that can be defined on startup that affect the behavior of ###
-### openbox. ###
+### Options that can be changed to adjust the behavior of Openbox. ###
#############################################################################
-# theme - the theme used to decorate everything.
-theme = "/usr/local/share/openbox/styles/fieron2"
-
-# titlebar_layout - 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.
-titlebar_layout = "DILMC"
-
-# double_click_delay - the number of milliseconds in which 2 clicks are
-# perceived as a double-click.
-double_click_delay = 300
-
-# drag_threshold - the amount of pixels that you have to drag the mouse before
-# motion events will start occuring.
-drag_threshold = 3
-
-# desktop_names - the name of each desktop
-desktop_names = ["one", "two", "three", "four", "five", "six", "seven", \
+THEME = "/usr/local/share/openbox/styles/fieron2"
+"""The theme used to decorate everything."""
+
+TITLEBAR_LAYOUT = "DILMC"
+"""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 - the number of desktops/workspaces which can be scrolled
-# between.
-number_of_desktops = 4
+NUMBER_OF_DESKTOPS = 4
+"""The number of desktops/workspaces which can be scrolled between."""
+#############################################################################
print "Loaded config.py"
import historyplacement # history window placement
# try focus something when nothing is focused
-focus.fallback = 1
+focus.FALLBACK = 1
# choose a default focus model
focusmodel.setup_click_focus() # use focusmodel.setup_sloppy_focus() instead to
def histplace(data):
if data.client.appClass() == "XTerm": return 0
return 1
-historyplacement.confirm_callback = histplace
+historyplacement.CONFIRM_CALLBACK = histplace
# run xterm from root clicks
# if you want linear cycling instead of stacked cycling, comment out the focus
# bindings above, and use these instead.
#import focuscycle
-#focuscycle.raise_window = 0 # don't raise windows when they're activated
+#focuscycle.RAISE_WINDOW = 0 # don't raise windows when they're activated
#ob.kbind(["A-Tab"], ob.KeyContext.All, focuscycle.next)
#ob.kbind(["A-S-Tab"], ob.KeyContext.All, focuscycle.previous)
###########################################################################
### Options that affect the behavior of the focus module. ###
###########################################################################
-avoid_skip_taskbar = 1
+AVOID_SKIP_TASKBAR = 1
"""Don't focus windows which have requested to not be displayed in taskbars.
You will still be able to focus the windows, but not through cycling, and
they won't be focused as a fallback if 'fallback' is enabled."""
-fallback = 0
+FALLBACK = 0
"""Send focus somewhere when nothing is left with the focus, if possible."""
###########################################################################
def _focusable(client, desktop):
if not client.normal(): return 0
if not (client.canFocus() or client.focusNotify()): return 0
- if avoid_skip_taskbar and client.skipTaskbar(): return 0
+ if AVOID_SKIP_TASKBAR and client.skipTaskbar(): return 0
desk = client.desktop()
if not (desk == 0xffffffff or desk == desktop): return 0
# move it to the top
_clients.remove(win)
_clients.insert(0, win)
- elif fallback:
+ elif FALLBACK:
# pass around focus
desktop = ob.openbox.screen(data.screen).desktop()
for w in _clients:
###########################################################################
### Options that affect the behavior of the focuscycle module. ###
###########################################################################
-raise_window = 1
+RAISE_WINDOW = 1
"""When cycling focus, raise the window chosen as well as focusing it. This
does not affect fallback focusing behavior."""
# See focus.avoid_skip_taskbar
while 1:
client = screen.client(t)
if client and focus._focusable(client, desktop) and client.focus():
- if raise_window:
+ if RAISE_WINDOW:
screen.raiseWindow(client)
return
if forward:
import windowplacement # fallback routines
##############################################################################
-### Options for the historyplacement module (Options in the ###
-### windowplacement module also apply!): ###
-### ###
-# ignore_requested_positions - When true, the placement algorithm will ###
-### attempt to place windows even when they ###
-### request a position (like XMMS). ###
-### Note this only applies to normal windows, ###
-### not to special cases like desktops and ###
-### docks. ###
-ignore_requested_positions = 0 ###
-### ###
-# fallback - The window placement algorithm that will be used when history ###
-### placement does not have a place for the window. ###
-fallback = windowplacement.random ###
-### ###
-# confirm_callback - set this to a function to have the function called ###
-### before attempting to place a window via history. If ###
-### the function returns 'true' then an attempt will be ###
-### made to place the window. If it returns 'false', the ###
-### fallback method will be directly applied instead. ###
-confirm_callback = 0 ###
-### ###
-# filename - The name of the file where history data will be stored. The ###
-### number of the screen is appended onto this filename. ###
-filename = 'historydb' ###
-### ###
+### Options for the historyplacement module (Options in the ###
+### windowplacement module also apply!) ###
##############################################################################
+IGNORE_REQUESTED_POSITIONS = 0
+"""When true, the placement algorithm will attempt to place windows even
+ when they request a position (like XMMS). Note this only applies to
+ normal windows, not to special cases like desktops and docks."""
+FALLBACK = windowplacement.random
+"""The window placement algorithm that will be used when history placement
+ does not have a place for the window."""
+CONFIRM_CALLBACK = 0
+"""Set this to a function to have the function called before attempting to
+ place a window via history. If the function returns a non-zero, then an
+ attempt will be made to place the window. If it returns zero, the
+ fallback method will be directly applied instead."""
+FILENAME = 'historydb'
+"""The name of the file where history data will be stored. The number of
+ the screen is appended onto this filename."""
+##############################################################################
+
+def place(data):
+ """Place a window usingthe history placement algorithm."""
+ _place(data)
+
+###########################################################################
+###########################################################################
+
+###########################################################################
+### Internal stuff, should not be accessed outside the module. ###
+###########################################################################
import otk
import ob
def _load(data):
global _data
- file = open(os.environ['HOME']+'/.openbox/'+filename+"."+str(data.screen),
+ file = open(os.environ['HOME']+'/.openbox/'+FILENAME+"."+str(data.screen),
'r')
if file:
# read data
def _save(data):
global _data
- file = open(os.environ['HOME']+'/.openbox/'+filename+"."+str(data.screen),
+ file = open(os.environ['HOME']+'/.openbox/'+FILENAME+"."+str(data.screen),
'w')
if file:
while len(_data)-1 < data.screen:
_data.append([])
return _find(screen, state) # try again
-def place(data):
+def _place(data):
global _data
if data.client:
- if not (ignore_requested_positions and data.client.normal()):
+ if not (IGNORE_REQUESTED_POSITIONS and data.client.normal()):
if data.client.positionRequested(): return
state = _create_state(data)
try:
- if not confirm_callback or confirm_callback(data):
+ if not CONFIRM_CALLBACK or CONFIRM_CALLBACK(data):
print "looking for : " + state.appname + " : " + \
state.appclass + " : " + state.role
print "No match in history"
except TypeError:
pass
- if fallback: fallback(data)
+ if FALLBACK: FALLBACK(data)
def _save_window(data):
global _data
############################################################################
#############################################################################
-### Options that can be modified to change the functions' behaviors. ###
-### ###
-# 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. ###
-edge_resistance = 10 ###
-### ###
-# move_popup - display a coordinates popup when moving windows. ###
-move_popup = 1 ###
-### ###
-# NOT IMPLEMENTED (yet?) ###
-# move_rubberband - display an outline while moving instead of moving the ###
-### actual window, until the move is completed. Good for ###
-### slower systems. ###
-move_rubberband = 0 ###
-### ###
-# resize_popup - display a size popup when resizing windows. ###
-resize_popup = 1 ###
-### ###
-# NOT IMPLEMENTED (yet?) ###
-# resize_rubberband - display an outline while resizing instead of ###
-### resizing the actual window, until the resize is ###
-### completed. Good for slower systems. ###
-resize_rubberband = 0 ###
-### ###
-# resize_nearest - 1 to resize from the corner nearest where the mouse ###
-### is, 0 to resize always from the bottom right corner. ###
-resize_nearest = 1 ###
-### ###
-### ###
-# Provides: ###
-# def move(data): ###
-# """Moves the window interactively. This should only be used with ###
-# MouseMotion events. If move_popup or move_rubberband is enabled, ###
-# then the end_move function needs to be bound as well.""" ###
-# def end_move(data): ###
-# """Complete the interactive move of a window.""" ###
-# def resize(data): ###
-# """Resizes the window interactively. This should only be used with ###
-# MouseMotion events""" ###
-# def end_resize(data): ###
-# """Complete the interactive resize of a window.""" ###
-### ###
+### Options that can be modified to change the functions' behaviors. ###
#############################################################################
+EDGE_RESISTANCE = 10
+"""The amount of resistance to provide to moving a window past a screen
+ boundary. Specify a value of 0 to disable edge resistance."""
+MOVE_POPUP = 1
+"""Display a coordinates popup when moving windows."
+MOVE_RUBBERBAND = 0
+"""NOT IMPLEMENTED (yet?)
+ Display an outline while moving instead of moving the actual window,
+ until the move is completed. Good for slower systems."""
+RESIZE_POPUP = 1
+"""Display a size popup when resizing windows."""
+RESIZE_RUBBERBAND = 0
+"""NOT IMPLEMENTED (yet?)
+ Display an outline while resizing instead of resizing the actual
+ window, until the resize is completed. Good for slower systems."""
+RESIZE_NEAREST = 1
+"""Non-zero to resize from the corner nearest where the mouse is, 0 to
+ resize always from the bottom right corner."""
+#############################################################################
+
+def move(data):
+ """Moves the window interactively. This should only be used with
+ MouseAction.Motion events. If MOVE_POPUP or MOVE_RUBBERBAND 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 RESIZE_POPUP or RESIZE_RUBBERBAND 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)
+
+###########################################################################
+###########################################################################
+
+###########################################################################
+### Internal stuff, should not be accessed outside the module. ###
+###########################################################################
import ob
import otk
# have all the modifiers this started with been released?
if not _motion_mask & data.state:
if _inmove:
- end_move(data)
+ _end_move(data)
elif _inresize:
- end_resize(data)
+ _end_resize(data)
else:
raise RuntimeError
x = _cx + _dx + _client.frame.rect().x() - _client.area().x()
y = _cy + _dy + _client.frame.rect().y() - _client.area().y()
- global edge_resistance
global _last_x, _last_y
- if edge_resistance:
+ if EDGE_RESISTANCE:
fs = _client.frame.size()
w = _client.area().width() + fs.left + fs.right
h = _client.area().height() + fs.top + fs.bottom
t = area.top()
b = area.bottom() - h + 1
# left screen edge
- if _last_x > x and x < l and x >= l - edge_resistance:
+ if _last_x > x and x < l and x >= l - EDGE_RESISTANCE:
x = l
# right screen edge
- if _last_x < x and x > r and x <= r + edge_resistance:
+ if _last_x < x and x > r and x <= r + EDGE_RESISTANCE:
x = r
# top screen edge
- if _last_y > y and y < t and y >= t - edge_resistance:
+ if _last_y > y and y < t and y >= t - EDGE_RESISTANCE:
y = t
# right screen edge
- if _last_y < y and y > b and y <= b + edge_resistance:
+ if _last_y < y and y > b and y <= b + EDGE_RESISTANCE:
y = b
global _inmove
_last_x = x
_last_y = y
- global move_rubberband
- if move_rubberband:
+ if MOVE_RUBBERBAND:
# draw the outline ...
f=0
else:
_client.move(x, y)
- global move_popup
- if move_popup:
+ if MOVE_POPUP:
global _popwidget, _poplabel
style = ob.openbox.screen(_screen).style()
font = style.labelFont()
_popwidget.height()) / 2)
_popwidget.show(1)
-def move(data):
- """Moves the window interactively. This should only be used with
- MouseMotion events. If move_popup or move_rubberband is enabled, then
- the end_move function needs to be bound as well."""
+def _move(data):
if not data.client: return
# not-normal windows dont get moved
ob.kgrab(_screen, _motion_grab)
_inmove = 1
-def end_move(data):
- """Complete the interactive move of a window."""
- global move_rubberband, _inmove
- global _popwidget, _poplabel
+def _end_move(data):
+ global MOVE_RUBBERBAND
+ global _inmove, _popwidget, _poplabel
if _inmove:
- r = move_rubberband
- move_rubberband = 0
+ r = MOVE_RUBBERBAND
+ MOVE_RUBBERBAND = 0
_do_move()
- move_rubberband = r
+ MOVE_RUBBERBAND = r
_inmove = 0
_poplabel = 0
_popwidget = 0
dy = _dy
# pick a corner to anchor
- if not (resize_nearest or _context == ob.MouseContext.Grip):
+ if not (RESIZE_NEAREST or _context == ob.MouseContext.Grip):
corner = ob.Client.TopLeft
else:
x = _px - _cx
w = _cw + dx
h = _ch + dy
- global resize_popup
- if resize_rubberband:
+ if RESIZE_RUBBERBAND:
# draw the outline ...
f=0
else:
_client.resize(corner, w, h)
- global resize_popup
- if resize_popup:
+ if RESIZE_POPUP:
global _popwidget, _poplabel
style = ob.openbox.screen(_screen).style()
ls = _client.logicalSize()
_popwidget.height()) / 2)
_popwidget.show(1)
-def resize(data):
- """Resizes the window interactively. This should only be used with
- MouseMotion events"""
+def _resize(data):
if not data.client: return
# not-normal windows dont get resized
ob.kgrab(_screen, _motion_grab)
_inresize = 1
-def end_resize(data):
- """Complete the interactive resize of a window."""
- global resize_rubberband, _inresize
+def _end_resize(data):
+ global RESIZE_RUBBERBAND, _inresize
global _popwidget, _poplabel
if _inresize:
- r = resize_rubberband
- resize_rubberband = 0
+ r = RESIZE_RUBBERBAND
+ RESIZE_RUBBERBAND = 0
_do_resize()
- resize_rubberband = r
+ RESIZE_RUBBERBAND = r
_inresize = 0
_poplabel = 0
_popwidget = 0
###########################################################################
### Options that affect the behavior of the stackedcycle module. ###
###########################################################################
-include_all_desktops = 0
+INCLUDE_ALL_DESKTOPS = 0
"""If this is non-zero then windows from all desktops will be included in
the stacking list."""
-include_icons = 1
+INCLUDE_ICONS = 1
"""If this is non-zero then windows which are iconified will be included
in the stacking list."""
-include_omnipresent = 1
+INCLUDE_OMNIPRESENT = 1
"""If this is non-zero then windows which are on all-desktops at once will
be included."""
-title_size_limit = 80
+TITLE_SIZE_LIMIT = 80
"""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."""
-activate_while_cycling = 1
+ACTIVATE_WHILE_CYCLING = 1
"""If this is non-zero then windows will be activated as they are
highlighted in the cycling list (except iconified windows)."""
-# See focus.avoid_skip_taskbar
-# See focuscycle.raise_window
+# See focus.AVOID_SKIP_TASKBAR
+# See focuscycle.RAISE_WINDOW
###########################################################################
def next(data):
import focus
import focuscycle
-class cycledata:
+class _cycledata:
def __init__(self):
self.cycling = 0
if not client.normal(): return 0
if not (client.canFocus() or client.focusNotify()): return 0
- if focus.avoid_skip_taskbar and client.skipTaskbar(): return 0
+ if focus.AVOID_SKIP_TASKBAR and client.skipTaskbar(): return 0
- if include_icons and client.iconic(): return 1
- if include_omnipresent and desk == 0xffffffff: return 1
- if include_all_desktops: return 1
+ if INCLUDE_ICONS and client.iconic(): return 1
+ if INCLUDE_OMNIPRESENT and desk == 0xffffffff: return 1
+ if INCLUDE_ALL_DESKTOPS: return 1
if desk == curdesk: return 1
return 0
if c.iconic(): t = c.iconTitle()
else: t = c.title()
- if len(t) > title_size_limit: # limit the length of titles
- t = t[:title_size_limit / 2 - 2] + "..." + \
- t[0 - title_size_limit / 2 - 2:]
+ if len(t) > TITLE_SIZE_LIMIT: # limit the length of titles
+ t = t[:TITLE_SIZE_LIMIT / 2 - 2] + "..." + \
+ t[0 - TITLE_SIZE_LIMIT / 2 - 2:]
length = font.measureString(t)
if length > longest: longest = length
w.setText(t)
# send a net_active_window message for the target
if final or not client.iconic():
- if final: r = focuscycle.raise_window
+ if final: r = focuscycle.RAISE_WINDOW
else: r = 0
ob.send_client_msg(self.screeninfo.rootWindow(),
otk.Property_atoms().openbox_active_window,
if self.menupos < 0: self.menupos = len(self.clients) - 1
elif self.menupos >= len(self.clients): self.menupos = 0
self.menuwidgets[self.menupos].focus()
- if activate_while_cycling:
+ if ACTIVATE_WHILE_CYCLING:
self.activatetarget(0) # activate, but dont deiconify/unshade/raise
def grabfunc(self, data):
ob.ebind(ob.EventAction.NewWindow, _newwindow)
ob.ebind(ob.EventAction.CloseWindow, _closewindow)
-_o = cycledata()
+_o = _cycledata()
print "Loaded stackedcycle.py"
// XXX: dont load this every time!!@*
long dblclick;
- if (!python_get_long("double_click_delay", &dblclick))
+ if (!python_get_long("DOUBLE_CLICK_DELAY", &dblclick))
dblclick = 300;
if (e.time - _release.time < (unsigned)dblclick &&
int dx = x_root - _posqueue[0]->pos.x();
int dy = y_root - _posqueue[0]->pos.y();
// XXX: dont get this from python every time!
- if (!python_get_long("drag_threshold", &threshold))
+ if (!python_get_long("DRAG_THRESHOLD", &threshold))
threshold = 0;
if (!(std::abs(dx) >= threshold || std::abs(dy) >= threshold))
return; // not at the threshold yet
const int sep = bevel + 1;
otk::ustring layout;
- if (!python_get_string("titlebar_layout", &layout))
+ if (!python_get_string("TITLEBAR_LAYOUT", &layout))
layout = "ILMC";
// this code ensures that the string only has one of each possible
// XXX: initialize the screen's style
/*
otk::ustring stylepath;
- python_get_string("theme", &stylepath);
+ python_get_string("THEME", &stylepath);
otk::Configuration sconfig(false);
sconfig.setFile(otk::expandTilde(stylepath.c_str()));
if (!sconfig.load()) {
// Set the net_desktop_names property
std::vector<otk::ustring> names;
- python_get_stringlist("desktop_names", &names);
+ python_get_stringlist("DESKTOP_NAMES", &names);
otk::Property::set(_info->rootWindow(),
otk::Property::atoms.net_desktop_names,
otk::Property::utf8, names);
_desktop = 0;
- if (!python_get_long("number_of_desktops", &_num_desktops))
+ if (!python_get_long("NUMBER_OF_DESKTOPS", &_num_desktops))
_num_desktops = 1;
changeNumDesktops(_num_desktops); // set the hint