Merge branch 'backport' into 3.4
authorMikael Magnusson <mikachu@gmail.com>
Fri, 14 May 2010 13:52:18 +0000 (15:52 +0200)
committerMikael Magnusson <mikachu@gmail.com>
Fri, 14 May 2010 13:52:18 +0000 (15:52 +0200)
68 files changed:
CHANGELOG
Makefile.am
configure.ac
data/autostart.sh.in
data/gnome-wm-properties/openbox.desktop
data/rc.xml
data/rc.xsd
doc/openbox.1.in
doc/openbox.1.sgml
openbox/actions.c
openbox/actions.h
openbox/actions/addremovedesktop.c
openbox/actions/all.c
openbox/actions/all.h
openbox/actions/cyclewindows.c
openbox/actions/desktop.c
openbox/actions/directionalwindows.c
openbox/actions/execute.c
openbox/actions/exit.c
openbox/actions/focus.c
openbox/actions/growtoedge.c
openbox/actions/if.c [deleted file]
openbox/actions/layer.c
openbox/actions/maximize.c
openbox/actions/moverelative.c
openbox/actions/moveresizeto.c
openbox/actions/movetoedge.c
openbox/actions/shadelowerraise.c [new file with mode: 0644]
openbox/client.c
openbox/client.h
openbox/client_menu.c
openbox/client_menu.h
openbox/config.c
openbox/config.h
openbox/dock.h
openbox/event.c
openbox/event.h
openbox/extensions.h
openbox/focus.c
openbox/focus.h
openbox/focus_cycle_popup.c
openbox/focus_cycle_popup.h
openbox/frame.c
openbox/grab.h
openbox/keyboard.h
openbox/menu.c
openbox/menu.h
openbox/menuframe.c
openbox/menuframe.h
openbox/modkeys.c
openbox/mouse.c
openbox/mouse.h
openbox/moveresize.c
openbox/openbox.c
openbox/openbox.h
openbox/popup.h
openbox/prompt.c
openbox/prop.h
openbox/resist.c
openbox/screen.c
openbox/screen.h
openbox/session.c
openbox/stacking.h
openbox/startupnotify.h
openbox/translate.c
parser/parse.c
parser/parse.h
themes/Clearlooks/openbox-3/themerc

index fd68f09..da5f871 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,318 @@
+3.4.11.1:
+  * Updated Polish translation.
+  * Fixed bug #4519 (Incorrect focus in reused windows).
+  * Lower the default submenu open/hide delay from 200ms to 100ms.
+  * Fix some more problems with gnome integration.
+  * Update Clearlooks theme.
+  * Some other small fixes.
+
+3.4.11:
+  * Update Hungarian, Japanese, and Latvian translations.
+  * Make xdg-autostart use the OPENBOX environment by default, so you can use
+    OnlyShowIn=OPENBOX in an autostart .desktop and it will work as expected.
+  * Don't close the menu when you hold control and execute something.
+  * Fix bug #4503 (Adjust who shows up in the Alt-Tab list using SKIP_TASKBAR).
+  * Fix flickering window when moving maximized window between monitors of
+    different sizes.
+  * Fix bug #4355 (Allow multiple escaped _'s in a menu label and allow
+    a menu shortcut to come after an escaped _).
+  * Remember the maximized state of a window when it goes fullscreen, and
+    restore it when leaving fullscreen state.
+  * Fix bug #4072 (Openbox is stopped by terminal applications writing to
+    stdout).
+  * Fix bug #4492 (Mistake in openbox-gnome-session check while setting up).
+  * Fix obxprop to make --root and --id work correctly.
+  * Add _OB_APP_ROLE/CLASS/NAME/TYPE properties (replaces _OB_ROLE/CLASS/NAME).
+  * Make the focus cycling popup dynamic when windows appear/disappear.
+  * Fix bug #4411 (Crash when window appears during focus cycling).
+  * Allow the user to specify which properties should be shown by obxprop.
+  * Fix tilde expansion in the Execute action
+  * Make Home and End keys move to the top/bottom of the active menu.
+  * Use the submenuShowDelay when navigating menus with the keyboard.
+
+3.4.10:
+  * Improve keyboard navigation in Openbox menus.
+  * Add a --root option and a manpage for obxprop.
+  * Use a negative value for submenuShowDelay and submenuHideDelay to cause
+    an infinite delay.  This means you have to click to show a submenu, rather
+    than just hover over it.
+  * Improved code for submenu show/hide delay.  Added the submenuHideDelay
+    config file option, under the "menu" section.
+  * Fixed bug #4464 (Typo in openbox-gnome-session script).
+  * Fixed bug #4436 (Focusing a window used to stop focus cycling).
+  * Renamed obprop to obxprop due to collision with Open Babel (See bug #4419).
+
+3.4.9:
+  * Allow focus to move while inside an Openbox menu, or during an interactive
+    action such as window cycling.
+  * Fixed bug #3717 (Empty dock interfered with move/grow to edge actions).
+  * Fixed bug #4411 (Crash when switching desktops and window cycling).
+  * Fixed bug #4377 (Window resistance against struts).
+  * Fixed bug #4035 (Prevent focus from moving under the mouse after
+    activating a window with an Openbox menu.
+  * Correct the value provided by the _NET_WORKAREA hint, so desktop icons
+    will place across all monitors.
+  * Don't hide submenus immediately when moving through the parent menu.
+    (Resolves request #3762).
+  * Fix for showing Openbox menus with multiple monitors, don't restrict them
+    to the monitor where the mouse is.
+  * Fixed bug #4023 (Allow the user to have multiple keys which perform the
+    same function in Openbox menus/move/resize.  E.g. two keys which are
+    both bound to Escape.
+  * Add a new obprop tool, which can be used to read the _OB_ROLE, _OB_NAME,
+    and _OB_CLASS (as well as any other UTF-8 window properties) off of a
+    window.
+  * Add _OB_ROLE, _OB_NAME, and _OB_CLASS hints on each window that show the
+    respective values for use in the rc.xml applications section, to modify
+    the window when it appears.
+  * Improve Openbox interoperability with gnome-session >= 2.24.
+  * Fixed bug #4040 (Remove desktop hints set by gdm in the openbox-session
+    scripts, so that Openbox can set the number of desktops (assuming
+    gnome-settings-daemon doesn't first)).
+  * Fix a bug in xdg-autostart preventing some .desktop files from working.
+  * Show the desktop pager popup on the primary monitor instead of on all
+    monitors.
+  * Add a new primaryMonitor config option, which is where Openbox popups
+    will appear.  Defaults to a fixed monitor, but can be made to behave as
+    before with the "active" value for it.
+  * Correct edge detection for move/grow to edge to properly use monitor edges
+    for multi-monitor setups.
+  * Change default window placement policy to stay on the active monitor for
+    multi-monitor setups.
+  * Fixed bug #1149 (Crash with some window icon sizes).
+  * Respond to all strut changes, fixes moving/hiding panels.
+  * Fix internal code to focus windows on other desktops correctly (Fixes
+    bug #4413).
+  * Focus correctness fixups for switching desktops.
+  * Fixed bug #4373 (Decoration bug for shaded maximized windows).
+  * Fixed bug #4350 (Allow a window to be made skip_taskbar but still get
+    focused by the user's rc.xml).
+  * Fixed bug #4307 (Set a minimum time for screenEdgeWarpTime).
+  * Fixed bug #4253 (Support for Solaris in openbox-session scripts).
+  * Fixed bug #3851 (Allow transient windows to be above helper windows).
+
+3.4.8:
+  * Updated translations: Slovak.
+  * Allow windows to change their decorations at any time (Fix for
+    Google Chrome).
+  * Make openbox-session to respect the $XDG_CONFIG_HOME environment variable.
+  * Fixed bug #4344 where borders were given to windows that should not have
+    them.
+  * Merge the SessionLogout and Exit actions.  They now test if connected to a
+    session manager and ask it to exit if so, or simply kill Openbox if not.
+  * Further tweaks to the _NET_ACTIVE_WINDOW message handling.  Use the same
+    logic for focus-stealing as is used when mapping a new window.
+  * Don't go out of our way any more to prevent focus from moving while the
+    keyboard is grabbed.
+  * Fix openbox-gnome-session when using gnome-session > 2.22.
+
+3.4.8-rc2:
+  * Updated translations: Italian, Croatian, Ukrainian.
+  * When resizing a window while focus cycling with bar=no, the bar no longer
+    reappears.
+  * Correctly handle shaped windows using the ShapeInput kind, this is used
+    by many composited apps to pass through clicks in their transparent areas.
+  * Fix the <monitor> per-app setting.
+  * Avoid using anonymous unions.
+  * Windows that had their decorations removed by per-app settings were still
+    placed as if they still had their decorations.
+  * Fix event handling not to ignore events on a window when they have an unmap
+    event in the queue, if that unmap event doesn't cause the window to be
+    unmanaged.
+  * Show the desktop switch on every monitor in xinerama.
+  * Fix interpretation of struts in xinerama where the screens have different
+    sizes.
+  * Add "next" and "prev" as possible <monitor> targets in the moveto and
+    resizeto actions.
+  * Allow escaping the _ used to mark the shortcut character in menu labels.
+    You can now change the (first) _ in a label to __, this will be displayed
+    as a single underscore. The rest of the _ in the string will be unaffected,
+    so only double the first one.
+  * Only replace ~ with the home directory when it is preceded by whitespace or
+    is at the start of the string, and when it is followed by a space, slash, or
+    the end of the string. This is implemented with GRegex, and so the required
+    glib version has been bumped to 2.14.
+  * Some other small fixes.
+
+3.4.8-rc1:
+  * Updated translations: Basque, Catalan, Turkish, Italian, Spanish, Russian.
+  * New translations: Danish, Turkish, Lithuanian.
+  * Set the _MOTIF_WM_INFO atom so urxvt uses motif hints for borderless mode.
+  * Properly escape the xml used in session files.
+  * Correct a 64-bit issue related to comparing timestamps.
+  * There is a sneaky sentence right at the end of a big paragraph in the
+    wm-spec document that says windows mapping with _NET_WM_USER_TIME=0 should
+    not be focused initially, honor this request.
+  * When moving a window to another desktop with following on, bring the
+    window's helper windows (for example gimp image windows with the toolbox
+    set to utility window).
+  * Change the _NET_ACTIVE_WINDOW messages again, if they originate from the
+    app and the window is on another desktop, just set the demands_attention
+    flag. If the event came from the user (ie pager/panel), then the window
+    is still moved to the current desktop.
+
+3.4.7.2:
+  * The system I used to generate the dist tarball didn't have the
+    docbook-to-man command so the manpages were empty.
+
+3.4.7.1:
+  * Not to be outdone by the cairo team, I introduced a bug in the last release
+    which made resizing not give any feedback. This is now fixed.
+
+3.4.7:
+  * Fully updated Czech, Simplified Chinese, Traditional Chinese, German,
+    French, Hungarian, Norwegian, Vietnamese, Dutch, Swedish, Finnish,
+    Brazilian Portuguese, Japanese and Portuguese translations
+  * Partially updated Spanish translation
+  * Add an example of the "force" option for the per-app placement options to
+    the default rc.xml file
+  * Add a new xdg-autostart script.  This will eventually end up in the PyXDG
+    distribution hopefully, but it is included in Openbox for now.  This script
+    runs things based on the freedesktop.org autostart specification.  You can
+    have it run GNOME, KDE, ROX, or XFCE specific things if you want.  The
+    new default system-wide autostart.sh script runs it automatically
+  * Update the default menu.xml to include a lot of common apps
+  * Fix white font shadows (negative shadowtint)
+  * Update the autostart.sh to find gnome-settings-daemon correctly, as the
+    GNOME people have moved it to libexec
+  * Fix focus possibly getting stolen when using the Focus action
+  * Drastically speed up rendering of Vertical and SplitVertical gradients
+  * Speed improvements also for Horizonal and Pyramid gradients
+  * Add new theme options, menu.overlap.x and menu.overlap.y options, that let
+    you independently control the horizontal and vertical position of submenus
+  * Change _NET_ACTIVE_WINDOW messages to not change the current desktop, but
+    to bring the window to the current desktop instead.  This is the industry
+    standard policy
+  * Use the pretty new openbox.png icon as the default window icon
+  * Allow matching per-application rules to windows by their window type
+    (normal, dialog, splash, etc).  The default rc.xml has more details
+  * Add new Openbox-themed prompt windows.  Use these prompt windows to ask
+    before killing off windows that aren't responding.  This also means we
+    don't need to ping every window constantly forever
+  * Add a new <prompt> option to the Execute action.  If this is set to a
+    string, a dialog will be shown with that string in it and "yes"/"no"
+    buttons.  The command to be executed will only be run if the user selects
+    "yes" in the dialog
+  * Add a new <prompt> option to the Exit action, which is a boolean (not a
+    string).  When true, Openbox will show a dialog confirming if you want to
+    exit.  The default is to show the prompt
+  * Reduce Openbox's memory footprint and speed up rendering through the use
+    of a new icon cache, so that Openbox only needs to keep 1 copy of an icon
+    when 100 different windows share it
+  * Make Openbox menus have the "menu type" hint for compositors to see and use
+  * Fix the MoveResizeTo action for negative coords (opposite edges)
+  * Fix key bindings getting lost if multiple bindings at the same level could
+    not be translated (Fixes VMWare causing Openbox keybindings to stop
+    working)
+  * Fix the resize popup box for terminal windows with a base size of 0 (show
+    the right size values for urxvt terminals)
+  * Fix some off-by-one bugs with the edge growing/shrinking code
+  * Add new theme options for menu line separators: menu.separator.color,
+    menu.separator.width, menu.separator.padding.width,
+    menu.separator.padding.height
+  * Add xfce-mcs-manager to the default autostart.sh, and run it automatically
+    when gnome-settings-daemon is not present to have GTK apps inherit settings
+    from the XFCE configuration tools
+  * Make the send-to-desktop menu in the client-menu indicate which is the current
+    desktop for omnipresent windows, and don't close it if just toggling
+    omni-presence when ctrl-clicking
+  * Add a new SessionLogout action that logs out through the session manager,
+    when running Openbox within a session manager such as within an
+    GNOME/Openbox or KDE/Openbox session.  The action includes a <prompt>
+    option which is similar to the Exit action's
+  * Add a new gdm-control command that lets you control gdm from within an X
+    session.  The gdm-control lets you change GDM's behaviour for when you end
+    the current session.  For instance, you can tell GDM to reboot, and
+    then immediately log out of the current session, and the computer will be
+    rebooted
+  * Show an information dialog when an error occurs for Openbox, such as when
+    the Execute action fails or when XML syntax errors are present in the
+    configuration files
+  * When making a window very narrow, don't draw buttons to the right of the title
+    on top of the ones on its left.
+
+3.4.6.1:
+  * Updated Clearlooks theme
+  * Add the force="yes/no" option for the per-app settings' <position> tag
+  * Raise and focus modal children and their direct parents together, improved
+    usability with direct modal transient windows
+  * Fix crash when using <raise> for NextWindow and there are no windows
+    to move focus to
+  * Add the <manageDesktops> option in the rc.xml <menu> section, which toggles
+    the "Manage Desktops" section appearing in the combined-client-list-menu
+  * Fix for menu headers showing the wrong text
+  * Fix for the <focusLast> behavior
+  * Treat modal direct children as one window with their parent consistently
+
+3.4.6:
+  * Added Basque translation
+  * Updated French, Vietnamese German, Simplified Chinese, Russian, Portuguese,
+    Brasilian Portuguese, Norwegian, and Finnish translations
+  * New Clearlooks theme, updated by David Barr
+  * Updated the previous Clearlooks theme, and renamed it to Clearlooks-3.4
+  * Allow dialog type windows to go fullscreen (Fixes Kpdf)
+  * Remove the extraneous top border for undecorated windows while maximized
+  * Fixes for keyboard modifiers (Alt-tab dialog getting stuck on screen for
+    some users)
+  * Automatically catch changes to the keyboard map and reconfigure the key
+    bindings on the fly
+  * Fix focus moving incorrectly sometimes with focus under mouse enabled
+  * Make default configuration focus the desktop when you right click
+  * Add the <bar> and <raise> options for all window cycling actions, allowing
+    you to have your target window temporarily raised above all others, and to
+    turn the focus target indicator bar off
+  * Improve the LastDesktop action to not remember desktops you skipped across
+  * Ignore mouse clicks that are made on override-redirect (unmanaged) windows
+  * When opening a menu with a key binding, don't use the key binding to run
+    something in the menu
+  * Add a <monitor> option for window placement, which gives you the option
+    to place new windows on the active monitor, or the monitor where the mouse
+    is, instead of on any monitor (for xinerama multihead setups)
+  * Add options for placing the window move/resize coordinate popup window in
+    a fixed position on screen, rather than relative to the window being
+    moved or resized
+  * Prevent the dock from auto-hiding completely offscreen if the theme has
+    no borders for it
+  * New icon
+  * Fix race condition when running things that want to grab the keyboard
+    (e.g. gnome-panel-control --main-menu)
+  * When dialog windows ask to not appear in the taskbar, still give them focus
+    in normal ways (fixes new GNOME session logout dialogs)
+  * Fix bug with resizing corners on certain parts of the window frame
+  * Ping applications to tell when they are running or have become frozen.
+    Show a [Not Responding] message in the title bar of windows which are
+    frozen.
+  * When closing a window which is [Not Responding], kill the window's process
+    if it is running on the same machine as Openbox.  Otherwise, just
+    disconnect
+    the window from the X display.  A second attempt to close a [Not
+    Responding]
+    window will kill it forcefully (kill -9).
+  * Fixes for internal timers
+  * Add a <wmclass> option for the execute action's startup-notification.  This
+    lets you tell Openbox that the application will map a window with the
+    specified class - for applications that do not support startup-notification
+    natively.
+  * Fix for empty dock taking up space onscreen after a reconfigure
+  * Reduce Openbox's additional memory footprint per-window and per-menu
+  * Faster horizontal gradient rendering
+  * Don't deiconify windows that aren't allowed to be directly iconified on
+    restart (eg toolbars), as they can be iconified by other means
+  * Improve support for fullscreen windows in xinerama (TwinView) and
+    multiple-screen setups
+  * Add a --config-file command line option, to specify an alternate
+    configuration file path
+
+3.4.5:
+  * Added Hungarian translation
+  * Updated Finnish, Russian, German and French translations
+  * Fixed some very minor memory leaks
+  * Hide the desktop popup when showing the focus popup
+  * Fix a crash when trying to access the More... menu of
+    client-list-combined-menu
+  * Fix the coordinate popup only showing up on the first monitor in xinerama
+  * Add --exit to exit the currently running openbox instance
+
 3.4.4:
   * Updated Traditional Chinese translation
   * Updated Norwegian translation
index 0be0e37..e2430e0 100644 (file)
@@ -175,7 +175,6 @@ openbox_openbox_SOURCES = \
        openbox/actions/fullscreen.c \
        openbox/actions/growtoedge.c \
        openbox/actions/iconify.c \
-       openbox/actions/if.c \
        openbox/actions/kill.c \
        openbox/actions/layer.c \
        openbox/actions/lower.c \
@@ -192,6 +191,7 @@ openbox_openbox_SOURCES = \
        openbox/actions/resizerelative.c \
        openbox/actions/restart.c \
        openbox/actions/shade.c \
+       openbox/actions/shadelowerraise.c \
        openbox/actions/showdesktop.c \
        openbox/actions/showmenu.c \
        openbox/actions/unfocus.c \
@@ -444,6 +444,7 @@ edit = $(SED) \
        -e 's!@version\@!$(VERSION)!' \
        -e 's!@configdir\@!$(configdir)!' \
        -e 's!@secretbindir\@!$(secretbindir)!' \
+       -e 's!@libexecdir\@!$(libexecdir)!' \
        -e 's!@bindir\@!$(bindir)!'
 
 data/autostart.sh: $(srcdir)/data/autostart.sh.in Makefile
@@ -542,12 +543,14 @@ CLEANFILES = \
        doc/openbox-session.1 \
        doc/openbox-gnome-session.1 \
        doc/openbox-kde-session.1 \
+       doc/obxprop.1 \
        data/xsession/openbox-session \
        data/xsession/openbox-gnome-session \
        data/xsession/openbox-kde-session \
        data/xsession/openbox.desktop \
        data/xsession/openbox-gnome.desktop \
-       data/xsession/openbox-kde.desktop
+       data/xsession/openbox-kde.desktop \
+       data/autostart.sh
 
 #doc:
 #       $(MAKE) -$(MAKEFLAGS) -C doc/doxygen doc
index eb11c03..ef3c4bb 100644 (file)
@@ -1,5 +1,5 @@
 AC_PREREQ([2.54])
-AC_INIT([openbox], [3.999.0], [http://bugzilla.icculus.org])
+AC_INIT([openbox], [3.4.11.1], [http://bugzilla.icculus.org])
 AM_INIT_AUTOMAKE
 AC_CONFIG_SRCDIR([openbox/openbox.c])
 
@@ -15,9 +15,9 @@ dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match
 dnl
 OB_MAJOR_VERSION=3
 OB_MINOR_VERSION=4
-OB_MICRO_VERSION=16
-OB_INTERFACE_AGE=0
-OB_BINARY_AGE=0
+OB_MICRO_VERSION=29
+OB_INTERFACE_AGE=8
+OB_BINARY_AGE=8
 OB_VERSION=$PACKAGE_VERSION
 
 AC_SUBST(OB_MAJOR_VERSION)
index eb55558..910e5e8 100644 (file)
@@ -22,8 +22,8 @@ if which dbus-launch >/dev/null && test -z "$DBUS_SESSION_BUS_ADDRESS"; then
 fi
 
 # Make GTK apps look and behave how they were set up in the gnome config tools
-if test -x /usr/libexec/gnome-settings-daemon >/dev/null; then
-  /usr/libexec/gnome-settings-daemon &
+if test -x @libexecdir@/gnome-settings-daemon >/dev/null; then
+  @libexecdir@/gnome-settings-daemon &
 elif which gnome-settings-daemon >/dev/null; then
   gnome-settings-daemon &
 # Make GTK apps look and behave how they were set up in the XFCE config tools
index 23e690e..67e49e4 100644 (file)
@@ -1,4 +1,5 @@
 [Desktop Entry]
+Type=Application
 Name=Openbox
 Exec=openbox
 
index a576ca6..1b947b5 100644 (file)
 
   <!-- Keybindings for desktop switching -->
   <keybind key="C-A-Left">
-    <action name="GoToDesktop"><to>left</to><wrap>no</wrap></action>
+    <action name="DesktopLeft"><dialog>no</dialog><wrap>no</wrap></action>
   </keybind>
   <keybind key="C-A-Right">
-    <action name="GoToDesktop"><to>right</to><wrap>no</wrap></action>
+    <action name="DesktopRight"><dialog>no</dialog><wrap>no</wrap></action>
   </keybind>
   <keybind key="C-A-Up">
-    <action name="GoToDesktop"><to>up</to><wrap>no</wrap></action>
+    <action name="DesktopUp"><dialog>no</dialog><wrap>no</wrap></action>
   </keybind>
   <keybind key="C-A-Down">
-    <action name="GoToDesktop"><to>down</to><wrap>no</wrap></action>
+    <action name="DesktopDown"><dialog>no</dialog><wrap>no</wrap></action>
   </keybind>
   <keybind key="S-A-Left">
-    <action name="SendToDesktop"><to>left</to><wrap>no</wrap></action>
+    <action name="SendToDesktopLeft"><dialog>no</dialog><wrap>no</wrap></action>
   </keybind>
   <keybind key="S-A-Right">
-    <action name="SendToDesktop"><to>right</to><wrap>no</wrap></action>
+    <action name="SendToDesktopRight"><dialog>no</dialog><wrap>no</wrap></action>
   </keybind>
   <keybind key="S-A-Up">
-    <action name="SendToDesktop"><to>up</to><wrap>no</wrap></action>
+    <action name="SendToDesktopUp"><dialog>no</dialog><wrap>no</wrap></action>
   </keybind>
   <keybind key="S-A-Down">
-    <action name="SendToDesktop"><to>down</to><wrap>no</wrap></action>
+    <action name="SendToDesktopDown"><dialog>no</dialog><wrap>no</wrap></action>
   </keybind>
   <keybind key="W-F1">
-    <action name="GoToDesktop"><to>1</to></action>
+    <action name="Desktop"><desktop>1</desktop></action>
   </keybind>
   <keybind key="W-F2">
-    <action name="GoToDesktop"><to>2</to></action>
+    <action name="Desktop"><desktop>2</desktop></action>
   </keybind>
   <keybind key="W-F3">
-    <action name="GoToDesktop"><to>3</to></action>
+    <action name="Desktop"><desktop>3</desktop></action>
   </keybind>
   <keybind key="W-F4">
-    <action name="GoToDesktop"><to>4</to></action>
+    <action name="Desktop"><desktop>4</desktop></action>
   </keybind>
   <keybind key="W-d">
     <action name="ToggleShowDesktop"/>
 
   <!-- Keybindings for window switching -->
   <keybind key="A-Tab">
-    <action name="NextWindow">
-      <finalactions>
-        <action name="Focus"/>
-        <action name="Raise"/>
-        <action name="Unshade"/>
-      </finalactions>
-    </action>
+    <action name="NextWindow"/>
   </keybind>
   <keybind key="A-S-Tab">
-    <action name="PreviousWindow">
-      <finalactions>
-        <action name="Focus"/>
-        <action name="Raise"/>
-        <action name="Unshade"/>
-      </finalactions>
-    </action>
+    <action name="PreviousWindow"/>
   </keybind>
   <keybind key="C-A-Tab">
     <action name="NextWindow">
       <panels>yes</panels><desktop>yes</desktop>
-      <finalactions>
-        <action name="Focus"/>
-        <action name="Raise"/>
-        <action name="Unshade"/>
-      </finalactions>
     </action>
   </keybind>
 
     </mousebind>
 
     <mousebind button="A-Up" action="Click">
-      <action name="GoToDesktop"><to>previous</to></action>
+      <action name="DesktopPrevious"/>
     </mousebind>
     <mousebind button="A-Down" action="Click">
-      <action name="GoToDesktop"><to>next</to></action>
+      <action name="DesktopNext"/>
     </mousebind>
     <mousebind button="C-A-Up" action="Click">
-      <action name="GoToDesktop"><to>previous</to></action>
+      <action name="DesktopPrevious"/>
     </mousebind>
     <mousebind button="C-A-Down" action="Click">
-      <action name="GoToDesktop"><to>next</to></action>
+      <action name="DesktopNext"/>
     </mousebind>
     <mousebind button="A-S-Up" action="Click">
-      <action name="SendToDesktop"><to>previous</to></action>
+      <action name="SendToDesktopPrevious"/>
     </mousebind>
     <mousebind button="A-S-Down" action="Click">
-      <action name="SendToDesktop"><to>next</to></action>
+      <action name="SendToDesktopNext"/>
     </mousebind>
   </context>
 
       <action name="Move"/>
     </mousebind>
     <mousebind button="Left" action="DoubleClick">
-      <action name="ToggleMaximize"/>
+      <action name="ToggleMaximizeFull"/>
     </mousebind>
 
     <mousebind button="Middle" action="Press">
     <mousebind button="Left" action="Drag">
       <action name="Resize"><edge>left</edge></action>
     </mousebind>
+
+    <mousebind button="Right" action="Press">
+      <action name="Focus"/>
+      <action name="Raise"/>
+      <action name="ShowMenu"><menu>client-menu</menu></action>
+    </mousebind>
   </context>
 
   <context name="Right">
     <mousebind button="Left" action="Drag">
       <action name="Resize"><edge>right</edge></action>
     </mousebind>
+
+    <mousebind button="Right" action="Press">
+      <action name="Focus"/>
+      <action name="Raise"/>
+      <action name="ShowMenu"><menu>client-menu</menu></action>
+    </mousebind>
   </context>
 
   <context name="Bottom">
       <action name="Raise"/>
     </mousebind>
     <mousebind button="Left" action="Drag">
-      <action name="Resize"><edge>bottomleft</edge></action>
+      <action name="Resize"/>
     </mousebind>
   </context>
 
       <action name="Raise"/>
     </mousebind>
     <mousebind button="Left" action="Drag">
-      <action name="Resize"><edge>bottomright</edge></action>
+      <action name="Resize"/>
     </mousebind>
   </context>
 
       <action name="Unshade"/>
     </mousebind>
     <mousebind button="Left" action="Drag">
-      <action name="Resize"><edge>topleft</edge></action>
+      <action name="Resize"/>
     </mousebind>
   </context>
 
       <action name="Unshade"/>
     </mousebind>
     <mousebind button="Left" action="Drag">
-      <action name="Resize"><edge>topright</edge></action>
+      <action name="Resize"/>
     </mousebind>
   </context>
 
       <action name="Unshade"/>
     </mousebind>
     <mousebind button="Left" action="Click">
-      <action name="ToggleMaximize"/>
+      <action name="ToggleMaximizeFull"/>
     </mousebind>
     <mousebind button="Middle" action="Click">
-      <action name="ToggleMaximize"><direction>vertical</direction></action>
+      <action name="ToggleMaximizeVert"/>
     </mousebind>
     <mousebind button="Right" action="Click">
-      <action name="ToggleMaximize"><direction>horizontal</direction></action>
+      <action name="ToggleMaximizeHorz"/>
     </mousebind>
   </context>
 
   </context>
 
   <context name="Desktop">
-    <mousebind button="Up" action="Press">
-      <action name="GoToDesktop"><to>previous</to></action>
+    <mousebind button="Up" action="Click">
+      <action name="DesktopPrevious"/>
     </mousebind>
-    <mousebind button="Down" action="Press">
-      <action name="GoToDesktop"><to>next</to></action>
+    <mousebind button="Down" action="Click">
+      <action name="DesktopNext"/>
     </mousebind>
 
-    <mousebind button="A-Up" action="Press">
-      <action name="GoToDesktop"><to>previous</to></action>
+    <mousebind button="A-Up" action="Click">
+      <action name="DesktopPrevious"/>
     </mousebind>
-    <mousebind button="A-Down" action="Press">
-      <action name="GoToDesktop"><to>next</to></action>
+    <mousebind button="A-Down" action="Click">
+      <action name="DesktopNext"/>
     </mousebind>
-    <mousebind button="C-A-Up" action="Press">
-      <action name="GoToDesktop"><to>previous</to></action>
+    <mousebind button="C-A-Up" action="Click">
+      <action name="DesktopPrevious"/>
     </mousebind>
-    <mousebind button="C-A-Down" action="Press">
-      <action name="GoToDesktop"><to>next</to></action>
+    <mousebind button="C-A-Down" action="Click">
+      <action name="DesktopNext"/>
     </mousebind>
 
     <mousebind button="Left" action="Press">
   </context>
 
   <context name="MoveResize">
-    <mousebind button="Up" action="Press">
-      <action name="GoToDesktop"><to>previous</to></action>
+    <mousebind button="Up" action="Click">
+      <action name="DesktopPrevious"/>
     </mousebind>
-    <mousebind button="Down" action="Press">
-      <action name="GoToDesktop"><to>next</to></action>
+    <mousebind button="Down" action="Click">
+      <action name="DesktopNext"/>
     </mousebind>
-    <mousebind button="A-Up" action="Press">
-      <action name="GoToDesktop"><to>previous</to></action>
+    <mousebind button="A-Up" action="Click">
+      <action name="DesktopPrevious"/>
     </mousebind>
-    <mousebind button="A-Down" action="Press">
-      <action name="GoToDesktop"><to>next</to></action>
+    <mousebind button="A-Down" action="Click">
+      <action name="DesktopNext"/>
     </mousebind>
   </context>
 </mouse>
        menu is hidden again -->
   <middle>no</middle>
   <!-- center submenus vertically about the parent entry -->
-  <submenuShowDelay>200</submenuShowDelay>
+  <submenuShowDelay>100</submenuShowDelay>
   <!-- time to delay before showing a submenu after hovering over the parent
        entry.
        if this is a negative value, then the delay is infinite and the
index 499b81c..c51135b 100644 (file)
@@ -2,18 +2,10 @@
 
 <!-- XML Schema for the Openbox window manager configuration file -->
 
-<!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN"
-                               "http://www.w3.org/2001/XMLSchema.dtd" [
-<!ATTLIST schema xmlns:ob CDATA #IMPLIED>
-<!ENTITY % p "xsd:">
-<!ENTITY % s ":xsd">
-]>
-
 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
-    targetNamespace="http://openbox.org/4.0/rc"
-    xmlns:ob="http://openbox.org/4.0/rc"
-    elementFormDefault="qualified"
-    attributeFormDefault="unqualified">
+    targetNamespace="http://openbox.org/3.4/rc"
+    xmlns:ob="http://openbox.org/3.4/rc"
+    elementFormDefault="qualified">
     <!--
          root node
       -->
             <xsd:documentation>all these elements are expected in a openbox config file</xsd:documentation>
         </xsd:annotation>
         <xsd:complexType>
-            <xsd:all>
-                <xsd:element name="resistance" type="ob:resistance"/>
-                <xsd:element name="focus" type="ob:focus"/>
-                <xsd:element name="placement" type="ob:placement"/>
-                <xsd:element name="theme" type="ob:theme"/>
-                <xsd:element name="desktops" type="ob:desktops"/>
-                <xsd:element name="resize" type="ob:resize"/>
-                <xsd:element minOccurs="0" name="margins" type="ob:margins"/>
-                <xsd:element name="dock" type="ob:dock"/>
-                <xsd:element name="keyboard" type="ob:keyboard"/>
-                <xsd:element name="mouse" type="ob:mouse"/>
-                <xsd:element name="menu" type="ob:menu"/>
-                <xsd:element name="applications" type="ob:applications"/>
-            </xsd:all>
+            <xsd:element name="resistance" type="ob:resistance"/>
+            <xsd:element name="focus" type="ob:focus"/>
+            <xsd:element name="placement" type="ob:placement"/>
+            <xsd:element name="theme" type="ob:theme"/>
+            <xsd:element name="desktops" type="ob:desktops"/>
+            <xsd:element name="resize" type="ob:resize"/>
+            <xsd:element name="dock" type="ob:dock"/>
+            <xsd:element name="keyboard" type="ob:keyboard"/>
+            <xsd:element name="mouse" type="ob:mouse"/>
+            <xsd:element name="menu" type="ob:menu"/>
+            <xsd:element name="applications" type="ob:applications"/>
         </xsd:complexType>
     </xsd:element>
     <!--
         <xsd:annotation>
             <xsd:documentation>defines behaviour of windows when close to each other or the screen edge</xsd:documentation>
         </xsd:annotation>
-        <xsd:all>
-            <xsd:element minOccurs="0" name="strength" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="screen_edge_strength" type="xsd:integer"/>
-        </xsd:all>
+        <xsd:element minOccurs="0" name="strength" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="screen_edge_strength" type="xsd:integer"/>
     </xsd:complexType>
     <xsd:complexType name="focus">
         <xsd:annotation>
             <xsd:documentation>defines aspects of window focus</xsd:documentation>
         </xsd:annotation>
-        <xsd:all>
-            <xsd:element minOccurs="0" name="focusNew" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="focusLast" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="followMouse" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="underMouse" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="focusDelay" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="raiseOnFocus" type="ob:bool"/>
-        </xsd:all>
+        <xsd:element minOccurs="0" name="focusNew" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="focusLast" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="followMouse" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="underMouse" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="focusDelay" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="raiseOnFocus" type="ob:bool"/>
     </xsd:complexType>
     <xsd:complexType name="placement">
         <xsd:annotation>
             <xsd:documentation>defines how new windows are placed</xsd:documentation>
         </xsd:annotation>
-        <xsd:sequence>
-            <xsd:element minOccurs="0" name="policy" type="ob:placementpolicy"/>
-            <xsd:element minOccurs="0" name="center" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="monitor" type="ob:placementmonitor"/>
-        </xsd:sequence>
+        <xsd:element name="policy" type="ob:placementpolicy"/>
+        <xsd:element name="center" type="ob:bool"/>
+        <xsd:element name="monitor" type="ob:placementmonitor"/>
     </xsd:complexType>
     <xsd:complexType name="margins">
         <xsd:annotation>
             <xsd:documentation>defines desktop margins</xsd:documentation>
         </xsd:annotation>
-        <xsd:all>
-            <xsd:element minOccurs="0" name="top" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="left" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="right" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="bottom" type="xsd:integer"/>
-        </xsd:all>
+        <xsd:element minOccurs="0" name="top" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="left" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="right" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="bottom" type="xsd:integer"/>
     </xsd:complexType>              
     <xsd:complexType name="theme">
-        <xsd:sequence>
-            <xsd:element minOccurs="0" name="name" type="xsd:string"/>
-            <xsd:element minOccurs="0" name="titleLayout" type="xsd:string"/>
-            <xsd:element minOccurs="0" name="keepBorder" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="animateIconify" type="ob:bool"/>
-            <xsd:element minOccurs="0" maxOccurs="unbounded" name="font" type="ob:font"/>
-        </xsd:sequence>
+        <xsd:element minOccurs="0" name="name" type="xsd:string"/>
+        <xsd:element minOccurs="0" name="titleLayout" type="xsd:string"/>
+        <xsd:element minOccurs="0" name="keepBorder" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="animateIconify" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="font" type="ob:font"/>
     </xsd:complexType>
     <xsd:complexType name="font">
-        <xsd:all>
-            <xsd:element minOccurs="0" name="name" type="xsd:string"/>
-            <xsd:element minOccurs="0" name="size" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="weight" type="ob:fontweight"/>
-            <xsd:element minOccurs="0" name="slant" type="ob:fontslant"/>
-        </xsd:all>
+        <xsd:element minOccurs="0" name="name" type="xsd:string"/>
+        <xsd:element minOccurs="0" name="size" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="weight" type="ob:fontweight"/>
+        <xsd:element minOccurs="0" name="slant" type="ob:fontslant"/>
         <xsd:attribute name="place" type="ob:fontplace" use="required"/>
     </xsd:complexType>
     <xsd:complexType name="desktops">
         <xsd:annotation>
             <xsd:documentation>defines the number and names of desktops</xsd:documentation>
         </xsd:annotation>
-        <xsd:all>
-            <xsd:element minOccurs="0" name="number" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="firstdesk" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="names">
-                <xsd:complexType>
-                    <xsd:sequence>
-                        <xsd:element minOccurs="0" maxOccurs="unbounded" name="name" type="xsd:string"/>
-                    </xsd:sequence>
-                </xsd:complexType>
-            </xsd:element>
-            <xsd:element minOccurs="0" name="popupTime" type="xsd:integer"/>
-        </xsd:all>
+        <xsd:element minOccurs="0" name="number" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="firstdesk" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="names">
+            <xsd:complexType>
+                <xsd:element maxOccurs="unbounded" name="name" type="xsd:string"/>
+            </xsd:complexType>
+        </xsd:element>
+        <xsd:element minOccurs="0" name="popupTime" type="xsd:integer"/>
     </xsd:complexType>
     <xsd:complexType name="resize">
-        <xsd:all>
-            <xsd:element minOccurs="0" name="drawContents" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="popupShow" type="ob:popupshow"/>
-            <xsd:element minOccurs="0" name="popupPosition" type="ob:popupposition"/>
-            <xsd:element minOccurs="0" name="popupFixedPosition" type="ob:popupfixedposition"/>
-        </xsd:all>
+        <xsd:element minOccurs="0" name="drawContents" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="popupShow" type="ob:popupshow"/>
+        <xsd:element minOccurs="0" name="popupPosition" type="ob:popupposition"/>
+        <xsd:element minOccurs="0" name="popupPosition" type="ob:popupfixedposition"/>
     </xsd:complexType>
     <xsd:complexType name="popupfixedposition">
-        <xsd:all>
-            <xsd:element minOccurs="0" name="x" type="ob:center_or_int"/>
-            <xsd:element minOccurs="0" name="y" type="ob:center_or_int"/>
-        </xsd:all>
+        <xsd:element minOccurs="0" name="x" type="ob:center_or_int"/>
+        <xsd:element minOccurs="0" name="y" type="ob:center_or_int"/>
     </xsd:complexType>
     <xsd:complexType name="dock">
-        <xsd:all>
-            <xsd:element minOccurs="0" name="position" type="ob:dock_position"/>
-            <xsd:element minOccurs="0" name="floatingX" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="floatingY" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="noStrut" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="stacking" type="ob:layer"/>
-            <xsd:element minOccurs="0" name="direction" type="ob:direction"/>
-            <xsd:element minOccurs="0" name="autoHide" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="hideDelay" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="showDelay" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="moveButton" type="ob:button"/>
-        </xsd:all>
+        <xsd:element minOccurs="0" name="position" type="ob:dock_position"/>
+        <xsd:element minOccurs="0" name="floatingX" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="floatingY" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="noStrut" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="stacking" type="ob:layer"/>
+        <xsd:element minOccurs="0" name="direction" type="ob:direction"/>
+        <xsd:element minOccurs="0" name="autoHide" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="hideDelay" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="showDelay" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="moveButton" type="ob:button"/>
     </xsd:complexType>
     <xsd:complexType name="action">
-        <xsd:all>
-            <xsd:element minOccurs="0" name="execute" type="xsd:string"/>
-            <xsd:element minOccurs="0" name="startupnotify" type="ob:notify"/>
-            <xsd:element minOccurs="0" name="command" type="xsd:string"/>
-            <xsd:element minOccurs="0" name="allDesktops" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="menu" type="xsd:string"/>
-            <xsd:element minOccurs="0" name="delta" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="x" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="y" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="left" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="right" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="up" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="down" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="desktop">
-                <xsd:simpleType>
-                    <xsd:union memberTypes="xsd:integer ob:bool"/>
-                </xsd:simpleType>
-            </xsd:element>
-            <xsd:element minOccurs="0" name="edge" type="xsd:string"/>
-            <xsd:element minOccurs="0" name="wrap" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="follow" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="dialog" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="panels" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="here" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="linear" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="group" type="ob:bool"/>
-        </xsd:all>
+        <xsd:element minOccurs="0" name="execute" type="xsd:string"/>
+        <xsd:element minOccurs="0" name="command" type="xsd:string"/>
+        <xsd:element minOccurs="0" name="menu" type="xsd:string"/>
+        <xsd:element minOccurs="0" name="delta" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="x" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="y" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="left" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="right" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="up" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="down" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="desktop" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="wrap" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="follow" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="dialog" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="panels" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="here" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="linear" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="group" type="ob:bool"/>
         <xsd:attribute name="name" type="ob:actionname" use="required"/>
     </xsd:complexType>
     <xsd:complexType name="keybind">
         <xsd:attribute name="key" type="ob:keyname" use="required"/>
     </xsd:complexType>
     <xsd:complexType name="keyboard">
-        <xsd:sequence>
-            <xsd:element minOccurs="0" name="chainQuitKey" type="ob:keyname"/>
-            <xsd:element maxOccurs="unbounded" name="keybind" type="ob:keybind"/>
-        </xsd:sequence>
+        <xsd:element minOccurs="0" name="chainQuitKey" type="ob:keyname"/>
+        <xsd:element maxOccurs="unbounded" name="keybind" type="ob:keybind"/>
     </xsd:complexType>
     <xsd:complexType name="mousebind">
-        <xsd:sequence>
-            <xsd:element maxOccurs="unbounded" name="action" type="ob:action"/>
-        </xsd:sequence>
+        <xsd:element maxOccurs="unbounded" name="action" type="ob:action"/>
         <xsd:attribute name="action" type="ob:mouseaction" use="required"/>
         <xsd:attribute name="button" type="ob:button" use="required"/>
     </xsd:complexType>
     <xsd:complexType name="context">
-        <xsd:sequence>
-            <xsd:element maxOccurs="unbounded" name="mousebind" type="ob:mousebind"/>
-        </xsd:sequence>
+        <xsd:element maxOccurs="unbounded" name="mousebind" type="ob:mousebind"/>
         <xsd:attribute name="name" type="ob:contextname" use="required"/>
     </xsd:complexType>
     <xsd:complexType name="mouse">
-        <xsd:sequence>
-            <xsd:element minOccurs="0" name="dragThreshold" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="doubleClickTime" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="screenEdgeWarpTime" type="xsd:integer"/>
-            <xsd:element maxOccurs="unbounded" name="context" type="ob:context"/>
-        </xsd:sequence>
+        <xsd:element minOccurs="0" name="dragThreshold" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="doubleClickTime" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="screenEdgeWarpTime" type="xsd:integer"/>
+        <xsd:element maxOccurs="unbounded" name="context" type="ob:context"/>
     </xsd:complexType>
     <xsd:complexType name="menu">
-        <xsd:sequence>
-            <xsd:element maxOccurs="unbounded" name="file" type="xsd:string"/>
-            <xsd:element minOccurs="0" name="hideDelay" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="middle" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="submenuShowDelay" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="applicationIcons" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="manageDesktops" type="ob:bool"/>
-        </xsd:sequence>
+        <xsd:element maxOccurs="unbounded" name="file" type="xsd:string"/>
+        <xsd:element minOccurs="0" name="hideDelay" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="middle" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="submenuShowDelay" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="applicationIcons" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="manageDesktops" type="ob:bool"/>
     </xsd:complexType>
     <xsd:complexType name="window_position">
-        <xsd:all>
-            <xsd:element name="x" type="ob:center_or_int"/>
-            <xsd:element name="y" type="ob:center_or_int"/>
-            <xsd:element minOccurs="0" name="monitor" type="ob:mouse_or_int"/>    
-            <xsd:element minOccurs="0" name="head" type="xsd:string"/>
-        </xsd:all>
+        <xsd:element name="x" type="ob:center_or_int"/>
+        <xsd:element name="y" type="ob:center_or_int"/>
+       <xsd:element name="monitor" type="ob:mouse_or_int"/>    
+        <xsd:element minOccurs="0" name="head" type="xsd:string"/>
         <xsd:attribute name="force" type="ob:bool"/>
     </xsd:complexType>
     <xsd:complexType name="application">
-        <xsd:all>
-            <xsd:element minOccurs="0" name="decor" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="shade" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="position" type="ob:window_position"/>
-            <xsd:element minOccurs="0" name="focus" type="xsd:string"/>
-            <xsd:element minOccurs="0" name="desktop" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="layer" type="ob:layer"/>
-            <xsd:element minOccurs="0" name="iconic" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="skip_pager" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="skip_taskbar" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="fullscreen" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="maximized" type="ob:maximization"/>
-        </xsd:all>
+        <xsd:element minOccurs="0" name="decor" type="xsd:bool"/>
+        <xsd:element minOccurs="0" name="shade" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="position" type="ob:window_position"/>
+        <xsd:element minOccurs="0" name="focus" type="xsd:string"/>
+        <xsd:element minOccurs="0" name="desktop" type="xsd:integer"/>
+        <xsd:element minOccurs="0" name="layer" type="ob:layer"/>
+        <xsd:element minOccurs="0" name="iconic" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="skip_pager" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="skip_taskbar" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="fullscreen" type="ob:bool"/>
+        <xsd:element minOccurs="0" name="maximized" type="ob:maximization"/>
         <xsd:attribute name="role" type="xsd:string"/>
         <xsd:attribute name="type" type="ob:clienttype"/>
         <!-- at least one of these must be present -->
         <xsd:attribute name="class" type="xsd:string"/>
     </xsd:complexType>
     <xsd:complexType name="applications">
-        <xsd:sequence>
-            <xsd:element minOccurs="0" maxOccurs="unbounded" name="application" type="ob:application"/>
-        </xsd:sequence>
-    </xsd:complexType>
-    <xsd:complexType name="notify">
-        <xsd:all>
-            <xsd:element minOccurs="0" name="enabled" type="ob:bool"/>
-            <xsd:element minOccurs="0" name="name" type="xsd:string"/>
-            <xsd:element minOccurs="0" name="icon" type="xsd:string"/>
-        </xsd:all>
+        <xsd:element minOccurs="0" maxOccurs="unbounded" name="application" type="ob:application"/>
     </xsd:complexType>
     <!--
          simple types / restrictions
       -->
     <xsd:simpleType name="actionname">
         <xsd:restriction base="xsd:string">
-            <xsd:pattern value="[Ii][Ff]"/>
-            <xsd:pattern value="[Aa][Cc][Tt][Ii][Vv][Aa][Tt][Ee]"/>
-            <xsd:pattern value="[Bb][Rr][Ee][Aa][Kk][Cc][Hh][Rr][Oo][Oo][Tt]"/>
-            <xsd:pattern value="[Cc][Ll][Oo][Ss][Ee]"/>
-            <xsd:pattern value="[Dd][Ee][Ss][Kk][Tt][Oo][Pp]"/>
-            <xsd:pattern value="[Dd][Ee][Ss][Kk][Tt][Oo][Pp][Dd][Oo][Ww][Nn]"/>
-            <xsd:pattern value="[Dd][Ee][Ss][Kk][Tt][Oo][Pp][Ll][Aa][Ss][Tt]"/>
-            <xsd:pattern value="[Dd][Ee][Ss][Kk][Tt][Oo][Pp][Ll][Ee][Ff][Tt]"/>
-            <xsd:pattern value="[Dd][Ee][Ss][Kk][Tt][Oo][Pp][Nn][Ee][Xx][Tt]"/>
-            <xsd:pattern value="[Dd][Ee][Ss][Kk][Tt][Oo][Pp][Pp][Rr][Ee][Vv][Ii][Oo][Uu][Ss]"/>
-            <xsd:pattern value="[Dd][Ee][Ss][Kk][Tt][Oo][Pp][Rr][Ii][Gg][Hh][Tt]"/>
-            <xsd:pattern value="[Dd][Ee][Ss][Kk][Tt][Oo][Pp][Uu][Pp]"/>
-            <xsd:pattern value="[Dd][Ii][Rr][Ee][Cc][Tt][Ii][Oo][Nn][Aa][Ll][Ff][Oo][Cc][Uu][Ss][Ee][Aa][Ss][Tt]"/>
-            <xsd:pattern value="[Dd][Ii][Rr][Ee][Cc][Tt][Ii][Oo][Nn][Aa][Ll][Ff][Oo][Cc][Uu][Ss][Nn][Oo][Rr][Tt][Hh]"/>
-            <xsd:pattern value="[Dd][Ii][Rr][Ee][Cc][Tt][Ii][Oo][Nn][Aa][Ll][Ff][Oo][Cc][Uu][Ss][Nn][Oo][Rr][Tt][Hh][Ee][Aa][Ss][Tt]"/>
-            <xsd:pattern value="[Dd][Ii][Rr][Ee][Cc][Tt][Ii][Oo][Nn][Aa][Ll][Ff][Oo][Cc][Uu][Ss][Nn][Oo][Rr][Tt][Hh][Ww][Ee][Ss][Tt]"/>
-            <xsd:pattern value="[Dd][Ii][Rr][Ee][Cc][Tt][Ii][Oo][Nn][Aa][Ll][Ff][Oo][Cc][Uu][Ss][Ss][Oo][Uu][Tt][Hh]"/>
-            <xsd:pattern value="[Dd][Ii][Rr][Ee][Cc][Tt][Ii][Oo][Nn][Aa][Ll][Ff][Oo][Cc][Uu][Ss][Ss][Oo][Uu][Tt][Hh][Ee][Aa][Ss][Tt]"/>
-            <xsd:pattern value="[Dd][Ii][Rr][Ee][Cc][Tt][Ii][Oo][Nn][Aa][Ll][Ff][Oo][Cc][Uu][Ss][Ss][Oo][Uu][Tt][Hh][Ww][Ee][Ss][Tt]"/>
-            <xsd:pattern value="[Dd][Ii][Rr][Ee][Cc][Tt][Ii][Oo][Nn][Aa][Ll][Ff][Oo][Cc][Uu][Ss][Ww][Ee][Ss][Tt]"/>
-            <xsd:pattern value="[Ee][Xx][Ee][Cc][Uu][Tt][Ee]"/>
-            <xsd:pattern value="[Ee][Xx][Ii][Tt]"/>
-            <xsd:pattern value="[Ss][Ee][Ss][Ss][Ii][Oo][Nn][Ll][Oo][Gg][Oo][Uu][Tt]"/>
-            <xsd:pattern value="[Ff][Oo][Cc][Uu][Ss]"/>
-            <xsd:pattern value="[Ff][Oo][Cc][Uu][Ss][Tt][Oo][Bb][Oo][Tt][Tt][Oo][Mm]"/>
-            <xsd:pattern value="[Gg][Rr][Oo][Ww][Tt][Oo][Ee][Dd][Gg][Ee][Ee][Aa][Ss][Tt]"/>
-            <xsd:pattern value="[Gg][Rr][Oo][Ww][Tt][Oo][Ee][Dd][Gg][Ee][Nn][Oo][Rr][Tt][Hh]"/>
-            <xsd:pattern value="[Gg][Rr][Oo][Ww][Tt][Oo][Ee][Dd][Gg][Ee][Ss][Oo][Uu][Tt][Hh]"/>
-            <xsd:pattern value="[Gg][Rr][Oo][Ww][Tt][Oo][Ee][Dd][Gg][Ee][Ww][Ee][Ss][Tt]"/>
-            <xsd:pattern value="[Ii][Cc][Oo][Nn][Ii][Ff][Yy]"/>
-            <xsd:pattern value="[Kk][Ii][Ll][Ll]"/>
-            <xsd:pattern value="[Ll][Oo][Ww][Ee][Rr]"/>
-            <xsd:pattern value="[Mm][Aa][Xx][Ii][Mm][Ii][Zz][Ee][Ff][Uu][Ll][Ll]"/>
-            <xsd:pattern value="[Mm][Aa][Xx][Ii][Mm][Ii][Zz][Ee][Hh][Oo][Rr][Zz]"/>
-            <xsd:pattern value="[Mm][Aa][Xx][Ii][Mm][Ii][Zz][Ee][Vv][Ee][Rr][Tt]"/>
-            <xsd:pattern value="[Mm][Oo][Vv][Ee]"/>
-            <xsd:pattern value="[Mm][Oo][Vv][Ee][Rr][Ee][Ll][Aa][Tt][Ii][Vv][Ee]"/>
-            <xsd:pattern value="[Mm][Oo][Vv][Ee][Rr][Ee][Ll][Aa][Tt][Ii][Vv][Ee][Hh][Oo][Rr][Zz]"/>
-            <xsd:pattern value="[Mm][Oo][Vv][Ee][Rr][Ee][Ll][Aa][Tt][Ii][Vv][Ee][Vv][Ee][Rr][Tt]"/>
-            <xsd:pattern value="[Mm][Oo][Vv][Ee][Tt][Oo][Cc][Ee][Nn][Tt][Ee][Rr]"/>
-            <xsd:pattern value="[Mm][Oo][Vv][Ee][Ff][Rr][Oo][Mm][Ee][Dd][Gg][Ee][Ee][Aa][Ss][Tt]"/>
-            <xsd:pattern value="[Mm][Oo][Vv][Ee][Ff][Rr][Oo][Mm][Ee][Dd][Gg][Ee][Nn][Oo][Rr][Tt][Hh]"/>
-            <xsd:pattern value="[Mm][Oo][Vv][Ee][Ff][Rr][Oo][Mm][Ee][Dd][Gg][Ee][Ss][Oo][Uu][Tt][Hh]"/>
-            <xsd:pattern value="[Mm][Oo][Vv][Ee][Ff][Rr][Oo][Mm][Ee][Dd][Gg][Ee][Ww][Ee][Ss][Tt]"/>
-            <xsd:pattern value="[Mm][Oo][Vv][Ee][Tt][Oo][Ee][Dd][Gg][Ee][Ee][Aa][Ss][Tt]"/>
-            <xsd:pattern value="[Mm][Oo][Vv][Ee][Tt][Oo][Ee][Dd][Gg][Ee][Nn][Oo][Rr][Tt][Hh]"/>
-            <xsd:pattern value="[Mm][Oo][Vv][Ee][Tt][Oo][Ee][Dd][Gg][Ee][Ss][Oo][Uu][Tt][Hh]"/>
-            <xsd:pattern value="[Mm][Oo][Vv][Ee][Tt][Oo][Ee][Dd][Gg][Ee][Ww][Ee][Ss][Tt]"/>
-            <xsd:pattern value="[Nn][Ee][Xx][Tt][Ww][Ii][Nn][Dd][Oo][Ww]"/>
-            <xsd:pattern value="[Pp][Rr][Ee][Vv][Ii][Oo][Uu][Ss][Ww][Ii][Nn][Dd][Oo][Ww]"/>
-            <xsd:pattern value="[Rr][Aa][Ii][Ss][Ee]"/>
-            <xsd:pattern value="[Rr][Aa][Ii][Ss][Ee][Ll][Oo][Ww][Ee][Rr]"/>
-            <xsd:pattern value="[Rr][Ee][Cc][Oo][Nn][Ff][Ii][Gg][Uu][Rr][Ee]"/>
-            <xsd:pattern value="[Rr][Ee][Ss][Ii][Zz][Ee]"/>
-            <xsd:pattern value="[Rr][Ee][Ss][Ii][Zz][Ee][Rr][Ee][Ll][Aa][Tt][Ii][Vv][Ee]"/>
-            <xsd:pattern value="[Rr][Ee][Ss][Ii][Zz][Ee][Rr][Ee][Ll][Aa][Tt][Ii][Vv][Ee][Hh][Oo][Rr][Zz]"/>
-            <xsd:pattern value="[Rr][Ee][Ss][Ii][Zz][Ee][Rr][Ee][Ll][Aa][Tt][Ii][Vv][Ee][Vv][Ee][Rr][Tt]"/>
-            <xsd:pattern value="[Rr][Ee][Ss][Tt][Aa][Rr][Tt]"/>
-            <xsd:pattern value="[Ss][Ee][Nn][Dd][Tt][Oo][Bb][Oo][Tt][Tt][Oo][Mm][Ll][Aa][Yy][Ee][Rr]"/>
-            <xsd:pattern value="[Ss][Ee][Nn][Dd][Tt][Oo][Dd][Ee][Ss][Kk][Tt][Oo][Pp]"/>
-            <xsd:pattern value="[Ss][Ee][Nn][Dd][Tt][Oo][Dd][Ee][Ss][Kk][Tt][Oo][Pp][Dd][Oo][Ww][Nn]"/>
-            <xsd:pattern value="[Ss][Ee][Nn][Dd][Tt][Oo][Dd][Ee][Ss][Kk][Tt][Oo][Pp][Ll][Ee][Ff][Tt]"/>
-            <xsd:pattern value="[Ss][Ee][Nn][Dd][Tt][Oo][Dd][Ee][Ss][Kk][Tt][Oo][Pp][Nn][Ee][Xx][Tt]"/>
-            <xsd:pattern value="[Ss][Ee][Nn][Dd][Tt][Oo][Dd][Ee][Ss][Kk][Tt][Oo][Pp][Pp][Rr][Ee][Vv][Ii][Oo][Uu][Ss]"/>
-            <xsd:pattern value="[Ss][Ee][Nn][Dd][Tt][Oo][Dd][Ee][Ss][Kk][Tt][Oo][Pp][Rr][Ii][Gg][Hh][Tt]"/>
-            <xsd:pattern value="[Ss][Ee][Nn][Dd][Tt][Oo][Dd][Ee][Ss][Kk][Tt][Oo][Pp][Uu][Pp]"/>
-            <xsd:pattern value="[Ss][Ee][Nn][Dd][Tt][Oo][Nn][Oo][Rr][Mm][Aa][Ll][Ll][Aa][Yy][Ee][Rr]"/>
-            <xsd:pattern value="[Ss][Ee][Nn][Dd][Tt][Oo][Tt][Oo][Pp][Ll][Aa][Yy][Ee][Rr]"/>
-            <xsd:pattern value="[Ss][Hh][Aa][Dd][Ee]"/>
-            <xsd:pattern value="[Ss][Hh][Aa][Dd][Ee][Ll][Oo][Ww][Ee][Rr]"/>
-            <xsd:pattern value="[Ss][Hh][Oo][Ww][Dd][Ee][Ss][Kk][Tt][Oo][Pp]"/>
-            <xsd:pattern value="[Ss][Hh][Oo][Ww][Mm][Ee][Nn][Uu]"/>
-            <xsd:pattern value="[Tt][Oo][Gg][Gg][Ll][Ee][Aa][Ll][Ww][Aa][Yy][Ss][Oo][Nn][Bb][Oo][Tt][Tt][Oo][Mm]"/>
-            <xsd:pattern value="[Tt][Oo][Gg][Gg][Ll][Ee][Aa][Ll][Ww][Aa][Yy][Ss][Oo][Nn][Tt][Oo][Pp]"/>
-            <xsd:pattern value="[Tt][Oo][Gg][Gg][Ll][Ee][Dd][Ee][Cc][Oo][Rr][Aa][Tt][Ii][Oo][Nn][Ss]"/>
-            <xsd:pattern value="[Tt][Oo][Gg][Gg][Ll][Ee][Dd][Oo][Cc][Kk][Aa][Uu][Tt][Oo][Hh][Ii][Dd][Ee]"/>
-            <xsd:pattern value="[Tt][Oo][Gg][Gg][Ll][Ee][Ff][Uu][Ll][Ll][Ss][Cc][Rr][Ee][Ee][Nn]"/>
-            <xsd:pattern value="[Tt][Oo][Gg][Gg][Ll][Ee][Mm][Aa][Xx][Ii][Mm][Ii][Zz][Ee][Ff][Uu][Ll][Ll]"/>
-            <xsd:pattern value="[Tt][Oo][Gg][Gg][Ll][Ee][Mm][Aa][Xx][Ii][Mm][Ii][Zz][Ee][Hh][Oo][Rr][Zz]"/>
-            <xsd:pattern value="[Tt][Oo][Gg][Gg][Ll][Ee][Mm][Aa][Xx][Ii][Mm][Ii][Zz][Ee][Vv][Ee][Rr][Tt]"/>
-            <xsd:pattern value="[Tt][Oo][Gg][Gg][Ll][Ee][Oo][Mm][Nn][Ii][Pp][Rr][Ee][Ss][Ee][Nn][Tt]"/>
-            <xsd:pattern value="[Tt][Oo][Gg][Gg][Ll][Ee][Ss][Hh][Aa][Dd][Ee]"/>
-            <xsd:pattern value="[Tt][Oo][Gg][Gg][Ll][Ee][Ss][Hh][Oo][Ww][Dd][Ee][Ss][Kk][Tt][Oo][Pp]"/>
-            <xsd:pattern value="[Uu][Nn][Ff][Oo][Cc][Uu][Ss]"/>
-            <xsd:pattern value="[Uu][Nn][Mm][Aa][Xx][Ii][Mm][Ii][Zz][Ee][Ff][Uu][Ll][Ll]"/>
-            <xsd:pattern value="[Uu][Nn][Mm][Aa][Xx][Ii][Mm][Ii][Zz][Ee][Hh][Oo][Rr][Zz]"/>
-            <xsd:pattern value="[Uu][Nn][Mm][Aa][Xx][Ii][Mm][Ii][Zz][Ee][Vv][Ee][Rr][Tt]"/>
-            <xsd:pattern value="[Uu][Nn][Ss][Hh][Aa][Dd][Ee]"/>
-            <xsd:pattern value="[Uu][Nn][Ss][Hh][Aa][Dd][Ee][Rr][Aa][Ii][Ss][Ee]"/>
-            <xsd:pattern value="[Uu][Nn][Ss][Hh][Oo][Ww][Dd][Ee][Ss][Kk][Tt][Oo][Pp]"/>
+            <xsd:enumeration value="Activate"/>
+            <xsd:enumeration value="BreakChroot"/>
+            <xsd:enumeration value="Close"/>
+            <xsd:enumeration value="Desktop"/>
+            <xsd:enumeration value="DesktopDown"/>
+            <xsd:enumeration value="DesktopLast"/>
+            <xsd:enumeration value="DesktopLeft"/>
+            <xsd:enumeration value="DesktopNext"/>
+            <xsd:enumeration value="DesktopPrevious"/>
+            <xsd:enumeration value="DesktopRight"/>
+            <xsd:enumeration value="DesktopUp"/>
+            <xsd:enumeration value="DirectionalFocusEast"/>
+            <xsd:enumeration value="DirectionalFocusNorth"/>
+            <xsd:enumeration value="DirectionalFocusNortheast"/>
+            <xsd:enumeration value="DirectionalFocusNorthwest"/>
+            <xsd:enumeration value="DirectionalFocusSouth"/>
+            <xsd:enumeration value="DirectionalFocusSoutheast"/>
+            <xsd:enumeration value="DirectionalFocusSouthwest"/>
+            <xsd:enumeration value="DirectionalFocusWest"/>
+            <xsd:enumeration value="Execute"/>
+            <xsd:enumeration value="Exit"/>
+            <xsd:enumeration value="Focus"/>
+            <xsd:enumeration value="FocusToBottom"/>
+            <xsd:enumeration value="GrowToEdgeEast"/>
+            <xsd:enumeration value="GrowToEdgeNorth"/>
+            <xsd:enumeration value="GrowToEdgeSouth"/>
+            <xsd:enumeration value="GrowToEdgeWest"/>
+            <xsd:enumeration value="Iconify"/>
+            <xsd:enumeration value="Kill"/>
+            <xsd:enumeration value="Lower"/>
+            <xsd:enumeration value="MaximizeFull"/>
+            <xsd:enumeration value="MaximizeHorz"/>
+            <xsd:enumeration value="MaximizeVert"/>
+            <xsd:enumeration value="Move"/>
+            <xsd:enumeration value="MoveRelative"/>
+            <xsd:enumeration value="MoveRelativeHorz"/>
+            <xsd:enumeration value="MoveRelativeVert"/>
+            <xsd:enumeration value="MoveToCenter"/>
+            <xsd:enumeration value="MoveFromEdgeEast"/>
+            <xsd:enumeration value="MoveFromEdgeNorth"/>
+            <xsd:enumeration value="MoveFromEdgeSouth"/>
+            <xsd:enumeration value="MoveFromEdgeWest"/>
+            <xsd:enumeration value="MoveToEdgeEast"/>
+            <xsd:enumeration value="MoveToEdgeNorth"/>
+            <xsd:enumeration value="MoveToEdgeSouth"/>
+            <xsd:enumeration value="MoveToEdgeWest"/>
+            <xsd:enumeration value="NextWindow"/>
+            <xsd:enumeration value="PreviousWindow"/>
+            <xsd:enumeration value="Raise"/>
+            <xsd:enumeration value="RaiseLower"/>
+            <xsd:enumeration value="Reconfigure"/>
+            <xsd:enumeration value="Resize"/>
+            <xsd:enumeration value="ResizeRelative"/>
+            <xsd:enumeration value="ResizeRelativeHorz"/>
+            <xsd:enumeration value="ResizeRelativeVert"/>
+            <xsd:enumeration value="Restart"/>
+            <xsd:enumeration value="SendToBottomLayer"/>
+            <xsd:enumeration value="SendToDesktop"/>
+            <xsd:enumeration value="SendToDesktopDown"/>
+            <xsd:enumeration value="SendToDesktopLeft"/>
+            <xsd:enumeration value="SendToDesktopNext"/>
+            <xsd:enumeration value="SendToDesktopPrevious"/>
+            <xsd:enumeration value="SendToDesktopRight"/>
+            <xsd:enumeration value="SendToDesktopUp"/>
+            <xsd:enumeration value="SendToNormalLayer"/>
+            <xsd:enumeration value="SendToTopLayer"/>
+            <xsd:enumeration value="Shade"/>
+            <xsd:enumeration value="ShadeLower"/>
+            <xsd:enumeration value="ShowDesktop"/>
+            <xsd:enumeration value="ShowMenu"/>
+            <xsd:enumeration value="ToggleAlwaysOnBottom"/>
+            <xsd:enumeration value="ToggleAlwaysOnTop"/>
+            <xsd:enumeration value="ToggleDecorations"/>
+            <xsd:enumeration value="ToggleDockAutoHide"/>
+            <xsd:enumeration value="ToggleFullscreen"/>
+            <xsd:enumeration value="ToggleMaximizeFull"/>
+            <xsd:enumeration value="ToggleMaximizeHorz"/>
+            <xsd:enumeration value="ToggleMaximizeVert"/>
+            <xsd:enumeration value="ToggleOmnipresent"/>
+            <xsd:enumeration value="ToggleShade"/>
+            <xsd:enumeration value="ToggleShowDesktop"/>
+            <xsd:enumeration value="Unfocus"/>
+            <xsd:enumeration value="UnmaximizeFull"/>
+            <xsd:enumeration value="UnmaximizeHorz"/>
+            <xsd:enumeration value="UnmaximizeVert"/>
+            <xsd:enumeration value="Unshade"/>
+            <xsd:enumeration value="UnshadeRaise"/>
+            <xsd:enumeration value="UnShowDesktop"/>
         </xsd:restriction>
     </xsd:simpleType>
     <xsd:simpleType name="clienttype">
     </xsd:simpleType>
     <xsd:simpleType name="button">
         <xsd:restriction base="xsd:string">
-            <xsd:pattern value="(([ACMSW]|Mod[1-5])-){,5}(Left|Middle|Right|Up|Down|Button[0-9]+)"/>
+            <!-- FIXME what??? -->
+            <xsd:enumeration value="Left"/>
+            <xsd:enumeration value="Middle"/>
+            <xsd:enumeration value="Right"/>
+            <xsd:enumeration value="Up"/>
+            <xsd:enumeration value="Down"/>
+            <xsd:enumeration value="A-Left"/>
+            <xsd:enumeration value="A-Middle"/>
+            <xsd:enumeration value="A-Right"/>
+            <xsd:enumeration value="A-Up"/>
+            <xsd:enumeration value="A-Down"/>
+            <xsd:enumeration value="C-A-Left"/>
+            <xsd:enumeration value="C-A-Middle"/>
+            <xsd:enumeration value="C-A-Right"/>
+            <xsd:enumeration value="C-A-Up"/>
+            <xsd:enumeration value="C-A-Down"/>
         </xsd:restriction>
     </xsd:simpleType>
     <xsd:simpleType name="center_or_int">
         <xsd:restriction base="xsd:string">
             <!-- ob: atoi($_) unless $_ eq 'center'; -->
             <!-- I think the regexp DTRT WRT atoi. -->
-            <xsd:pattern value="center|-?(0|[1-9][0-9]*)"/>
+            <xsd:pattern value="center|0|[1-9][0-9]*"/>
         </xsd:restriction>
     </xsd:simpleType>
     <xsd:simpleType name="mouse_or_int">
             <xsd:enumeration value="Left"/>
             <xsd:enumeration value="Right"/>
             <xsd:enumeration value="Bottom"/>
+            <xsd:enumeration value="Handle"/>
             <xsd:enumeration value="Maximize"/>
             <xsd:enumeration value="AllDesktops"/>
             <xsd:enumeration value="Shade"/>
         <xsd:restriction base="xsd:string">
             <!-- FIXME: M, Mod2, Mod5 in addition to S, A, C -->
             <!-- how do we do all substrings and permutations? -->
-            <xsd:pattern value="(([ACMSW]|Mod[1-5])-){,5}[a-zA-Z0-9]*"/>
+            <xsd:pattern value="(A-)?(S-)?(A-)?(C-)?(A-)?(S-)?(A-)?[a-zA-Z0-9]*"/>
         </xsd:restriction>
     </xsd:simpleType>
     <xsd:simpleType name="layer">
         <xsd:restriction base="xsd:string">
-            <xsd:pattern value="[Aa][Bb][Oo][Vv][Ee]"/>
-            <xsd:pattern value="[Nn][Oo][Rr][Mm][Aa][Ll]"/>
-            <xsd:pattern value="[Bb][Ee][Ll][Oo][Ww]"/>
+            <xsd:enumeration value="Above"/>
+            <xsd:enumeration value="Normal"/>
+            <xsd:enumeration value="Below"/>
         </xsd:restriction>
     </xsd:simpleType>
     <xsd:simpleType name="maximization">
index d508e8c..89183aa 100644 (file)
@@ -4,7 +4,7 @@ openbox \(em A minimalistic, highly configurable, next generation window
 manager with extensive standards support. 
 .SH "SYNOPSIS" 
 .PP 
-\fBopenbox\fR [\fB\-\-help\fP]  [\fB\-\-version\fP]  [\fB\-\-replace\fP]  [\fB\-\-reconfigure\fP]  [\fB\-\-restart\fP]  [\fB\-\-sm-disable\fP]  [\fB\-\-sync\fP]  [\fB\-\-debug\fP]  [\fB\-\-debug-focus\fP]  [\fB\-\-debug-xinerama\fP]  
+\fBopenbox\fR [\fB\-\-help\fP]  [\fB\-\-version\fP]  [\fB\-\-replace\fP]  [\fB\-\-reconfigure\fP]  [\fB\-\-restart\fP]  [\fB\-\-config-file FILE\fP]  [\fB\-\-sm-disable\fP]  [\fB\-\-sync\fP]  [\fB\-\-debug\fP]  [\fB\-\-debug-focus\fP]  [\fB\-\-debug-xinerama\fP]  
 .SH "DESCRIPTION" 
 .PP 
 Openbox is minimalistic, highly configurable, next generation window 
@@ -70,6 +70,9 @@ reload its configuration.
 If Openbox is already running on the display, tell it to 
 restart. This is useful if you have upgraded Openbox and don't 
 want to restart X. 
+.IP "\fB\-\-config-file FILE\fP" 10 
+Use FILE for configuration instead of looking for rc.xml 
+in the XDG search path. FILE is an absolute path. 
 .IP "\fB\-\-sm-disable\fP" 10 
 Do not connect to the session manager. 
 .IP "\fB\-\-sync\fP" 10 
@@ -92,4 +95,4 @@ The program's full documentation is available on the website:
 .PP 
 Please report bugs to: \fBhttp://bugzilla.icculus.org/ 
 \fP 
-.\" created by instant / docbook-to-man, Wed 06 Jan 2010, 13:40 
+.\" created by instant / docbook-to-man, Fri 26 Mar 2010, 01:55 
index 275c324..a06d0cf 100644 (file)
@@ -41,6 +41,7 @@ manpage.1: manpage.sgml
       <arg><option>--replace</option></arg>
       <arg><option>--reconfigure</option></arg>
       <arg><option>--restart</option></arg>
+      <arg><option>--config-file FILE</option></arg>
       <arg><option>--sm-disable</option></arg>
       <arg><option>--sync</option></arg>
       <arg><option>--debug</option></arg>
@@ -137,6 +138,13 @@ manpage.1: manpage.sgml
         </listitem>
       </varlistentry>
       <varlistentry>
+        <term><option>--config-file FILE</option></term>
+        <listitem>
+          <para>Use FILE for configuration instead of looking for rc.xml
+            in the XDG search path. FILE is an absolute path.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
         <term><option>--sm-disable</option></term>
         <listitem>
           <para>Do not connect to the session manager.</para>
index 948ac2c..a6a6ea4 100644 (file)
@@ -47,6 +47,7 @@ struct _ObActionsDefinition {
     ObActionsRunFunc run;
     ObActionsInteractiveInputFunc i_input;
     ObActionsInteractiveCancelFunc i_cancel;
+    ObActionsShutdownFunc shutdown;
 };
 
 struct _ObActionsAct {
@@ -73,7 +74,9 @@ void actions_shutdown(gboolean reconfig)
 
     /* free all the registered actions */
     while (registered) {
-        actions_definition_unref(registered->data);
+        ObActionsDefinition *d = registered->data;
+        if (d->shutdown) d->shutdown();
+        actions_definition_unref(d);
         registered = g_slist_delete_link(registered, registered);
     }
 }
@@ -105,12 +108,29 @@ gboolean actions_register(const gchar *name,
     def->run = run;
     def->i_input = i_input;
     def->i_cancel = i_cancel;
+    def->shutdown = NULL;
 
     registered = g_slist_prepend(registered, def);
 
     return TRUE;
 }
 
+gboolean actions_set_shutdown(const gchar *name,
+                              ObActionsShutdownFunc shutdown)
+{
+    GSList *it;
+    ObActionsDefinition *def;
+
+    for (it = registered; it; it = g_slist_next(it)) {
+        def = it->data;
+        if (!g_ascii_strcasecmp(name, def->name)) {
+            def->shutdown = shutdown;
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
 static void actions_definition_ref(ObActionsDefinition *def)
 {
     ++def->ref;
index 6db6f8d..7a98aab 100644 (file)
@@ -35,6 +35,7 @@ typedef gpointer (*ObActionsDataSetupFunc)(ObParseInst *i,
 typedef void     (*ObActionsDataFreeFunc)(gpointer options);
 typedef gboolean (*ObActionsRunFunc)(ObActionsData *data,
                                      gpointer options);
+typedef void     (*ObActionsShutdownFunc)(void);
 typedef gboolean (*ObActionsInteractiveInputFunc)(guint initial_state,
                                                   XEvent *e,
                                                   gpointer options,
@@ -64,9 +65,13 @@ gboolean actions_register(const gchar *name,
                           ObActionsInteractiveInputFunc i_input,
                           ObActionsInteractiveCancelFunc i_cancel);
 
+gboolean actions_set_shutdown(const gchar *name,
+                              ObActionsShutdownFunc shutdown);
+
 ObActionsAct* actions_parse(ObParseInst *i,
                             xmlDocPtr doc,
                             xmlNodePtr node);
+
 ObActionsAct* actions_parse_string(const gchar *name);
 
 gboolean actions_act_is_interactive(ObActionsAct *act);
@@ -81,7 +86,7 @@ void actions_act_unref(ObActionsAct *act);
 void actions_set_need_pointer_replay_before_move(gboolean replay);
 /*! Returns if a ReplayPointer is still needed.  If it was called while running
   actions then this will be false */
-gboolean actions_get_need_pointer_replay_before_move();
+gboolean actions_get_need_pointer_replay_before_move(void);
 
 /*! Pass in a GSList of ObActionsAct's to be run. */
 void actions_run_acts(GSList *acts,
@@ -93,8 +98,8 @@ void actions_run_acts(GSList *acts,
                       ObFrameContext con,
                       struct _ObClient *client);
 
-gboolean actions_interactive_act_running();
-void actions_interactive_cancel_act();
+gboolean actions_interactive_act_running(void);
+void actions_interactive_cancel_act(void);
 
 gboolean actions_interactive_input_event(XEvent *e);
 
index 8125b9b..2b90d08 100644 (file)
@@ -11,6 +11,14 @@ static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
 static gpointer setup_add_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
 static gpointer setup_remove_func(ObParseInst *i,
                                   xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_addcurrent_func(ObParseInst *i,
+                                      xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_addlast_func(ObParseInst *i,
+                                   xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_removecurrent_func(ObParseInst *i,
+                                      xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_removelast_func(ObParseInst *i,
+                                      xmlDocPtr doc, xmlNodePtr node);
 static void     free_func(gpointer options);
 static gboolean run_func(ObActionsData *data, gpointer options);
 
@@ -26,6 +34,26 @@ void action_addremovedesktop_startup(void)
                      free_func,
                      run_func,
                      NULL, NULL);
+    actions_register("AddDesktopLast",
+                     setup_addlast_func,
+                     free_func,
+                     run_func,
+                     NULL, NULL);
+    actions_register("RemoveDesktopLast",
+                     setup_removelast_func,
+                     free_func,
+                     run_func,
+                     NULL, NULL);
+    actions_register("AddDesktopCurrent",
+                     setup_addcurrent_func,
+                     free_func,
+                     run_func,
+                     NULL, NULL);
+    actions_register("RemoveDesktopCurrent",
+                     setup_removecurrent_func,
+                     free_func,
+                     run_func,
+                     NULL, NULL);
 }
 
 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
@@ -62,6 +90,38 @@ static gpointer setup_remove_func(ObParseInst *i,
     return o;
 }
 
+static gpointer setup_addcurrent_func(ObParseInst *i,
+                                      xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_add_func(i, doc, node);
+    o->current = TRUE;
+    return o;
+}
+
+static gpointer setup_addlast_func(ObParseInst *i,
+                                   xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_add_func(i, doc, node);
+    o->current = FALSE;
+    return o;
+}
+
+static gpointer setup_removecurrent_func(ObParseInst *i,
+                                      xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_remove_func(i, doc, node);
+    o->current = TRUE;
+    return o;
+}
+
+static gpointer setup_removelast_func(ObParseInst *i,
+                                      xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_remove_func(i, doc, node);
+    o->current = FALSE;
+    return o;
+}
+
 static void free_func(gpointer options)
 {
     Options *o = options;
index 47141ac..ac5b389 100644 (file)
@@ -36,6 +36,6 @@ void action_all_startup(void)
     action_layer_startup();
     action_movetoedge_startup();
     action_growtoedge_startup();
-    action_if_startup();
     action_focustobottom_startup();
+    action_shadelowerraise_startup();
 }
index 5f3f573..c84322f 100644 (file)
@@ -1,43 +1,43 @@
 #ifndef __actions_all_h
 #define __actions_all_h
 
-void action_all_startup();
+void action_all_startup(void);
 
-void action_execute_startup();
-void action_debug_startup();
-void action_showmenu_startup();
-void action_showdesktop_startup();
-void action_reconfigure_startup();
-void action_exit_startup();
-void action_restart_startup();
-void action_cyclewindows_startup();
-void action_breakchroot_startup();
-void action_close_startup();
-void action_move_startup();
-void action_focus_startup();
-void action_raise_startup();
-void action_lower_startup();
-void action_raiselower_startup();
-void action_unfocus_startup();
-void action_iconify_startup();
-void action_fullscreen_startup();
-void action_maximize_startup();
-void action_moveresizeto_startup();
-void action_moverelative_startup();
-void action_shade_startup();
-void action_kill_startup();
-void action_omnipresent_startup();
-void action_directionalwindows_startup();
-void action_resize_startup();
-void action_decorations_startup();
-void action_desktop_startup();
-void action_resizerelative_startup();
-void action_addremovedesktop_startup();
-void action_dockautohide_startup();
-void action_layer_startup();
-void action_movetoedge_startup();
-void action_growtoedge_startup();
-void action_if_startup();
-void action_focustobottom_startup();
+void action_execute_startup(void);
+void action_debug_startup(void);
+void action_showmenu_startup(void);
+void action_showdesktop_startup(void);
+void action_reconfigure_startup(void);
+void action_exit_startup(void);
+void action_restart_startup(void);
+void action_cyclewindows_startup(void);
+void action_breakchroot_startup(void);
+void action_close_startup(void);
+void action_move_startup(void);
+void action_focus_startup(void);
+void action_raise_startup(void);
+void action_lower_startup(void);
+void action_raiselower_startup(void);
+void action_unfocus_startup(void);
+void action_iconify_startup(void);
+void action_fullscreen_startup(void);
+void action_maximize_startup(void);
+void action_moveresizeto_startup(void);
+void action_moverelative_startup(void);
+void action_shade_startup(void);
+void action_kill_startup(void);
+void action_omnipresent_startup(void);
+void action_directionalwindows_startup(void);
+void action_resize_startup(void);
+void action_decorations_startup(void);
+void action_desktop_startup(void);
+void action_resizerelative_startup(void);
+void action_addremovedesktop_startup(void);
+void action_dockautohide_startup(void);
+void action_layer_startup(void);
+void action_movetoedge_startup(void);
+void action_growtoedge_startup(void);
+void action_focustobottom_startup(void);
+void action_shadelowerraise_startup(void);
 
 #endif
index 32d6a45..c26c55a 100644 (file)
@@ -4,6 +4,7 @@
 #include "openbox/event.h"
 #include "openbox/focus_cycle.h"
 #include "openbox/openbox.h"
+#include "openbox/client.h"
 #include "gettext.h"
 
 typedef struct {
index 0741615..e70acb0 100644 (file)
@@ -26,93 +26,236 @@ typedef struct {
     gboolean follow;
 } Options;
 
-static gpointer setup_go_func(ObParseInst *i, xmlDocPtr doc,
-                                  xmlNodePtr node);
-static gpointer setup_send_func(ObParseInst *i, xmlDocPtr doc,
-                                xmlNodePtr node);
+static gpointer setup_go_last_func(ObParseInst *i, xmlDocPtr doc,
+                                   xmlNodePtr node);
+static gpointer setup_send_last_func(ObParseInst *i, xmlDocPtr doc,
+                                     xmlNodePtr node);
+static gpointer setup_go_abs_func(ObParseInst *i, xmlDocPtr doc,
+                                   xmlNodePtr node);
+static gpointer setup_send_abs_func(ObParseInst *i, xmlDocPtr doc,
+                                     xmlNodePtr node);
+static gpointer setup_go_next_func(ObParseInst *i, xmlDocPtr doc,
+                                   xmlNodePtr node);
+static gpointer setup_send_next_func(ObParseInst *i, xmlDocPtr doc,
+                                     xmlNodePtr node);
+static gpointer setup_go_prev_func(ObParseInst *i, xmlDocPtr doc,
+                                   xmlNodePtr node);
+static gpointer setup_send_prev_func(ObParseInst *i, xmlDocPtr doc,
+                                     xmlNodePtr node);
+static gpointer setup_go_left_func(ObParseInst *i, xmlDocPtr doc,
+                                   xmlNodePtr node);
+static gpointer setup_send_left_func(ObParseInst *i, xmlDocPtr doc,
+                                     xmlNodePtr node);
+static gpointer setup_go_right_func(ObParseInst *i, xmlDocPtr doc,
+                                   xmlNodePtr node);
+static gpointer setup_send_right_func(ObParseInst *i, xmlDocPtr doc,
+                                     xmlNodePtr node);
+static gpointer setup_go_up_func(ObParseInst *i, xmlDocPtr doc,
+                                   xmlNodePtr node);
+static gpointer setup_send_up_func(ObParseInst *i, xmlDocPtr doc,
+                                     xmlNodePtr node);
+static gpointer setup_go_down_func(ObParseInst *i, xmlDocPtr doc,
+                                   xmlNodePtr node);
+static gpointer setup_send_down_func(ObParseInst *i, xmlDocPtr doc,
+                                     xmlNodePtr node);
 static gboolean run_func(ObActionsData *data, gpointer options);
 
 void action_desktop_startup(void)
 {
-    actions_register("GoToDesktop", setup_go_func, g_free, run_func,
-                     NULL, NULL);
-    actions_register("SendToDesktop", setup_send_func, g_free, run_func,
-                     NULL, NULL);
+    actions_register("DesktopLast", setup_go_last_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("SendToDesktopLast", setup_send_last_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("Desktop", setup_go_abs_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("SendToDesktop", setup_send_abs_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("DesktopNext", setup_go_next_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("SendToDesktopNext", setup_send_next_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("DesktopPrevious", setup_go_prev_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("SendToDesktopPrevious", setup_send_prev_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("DesktopLeft", setup_go_left_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("SendToDesktopLeft", setup_send_left_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("DesktopRight", setup_go_right_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("SendToDesktopRight", setup_send_right_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("DesktopUp", setup_go_up_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("SendToDesktopUp", setup_send_up_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("DesktopDown", setup_go_down_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("SendToDesktopDown", setup_send_down_func, g_free,
+                     run_func, NULL, NULL);
 }
 
-static gpointer setup_go_func(ObParseInst *i, xmlDocPtr doc,
-                                  xmlNodePtr node)
+static gpointer setup_follow(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
 {
     xmlNodePtr n;
-    Options *o;
+    Options *o = g_new0(Options, 1);
+    o->send = TRUE;
+    o->follow = TRUE;
+    if ((n = parse_find_node("follow", node)))
+        o->follow = parse_bool(doc, n);
+    return o;
+}
 
-    o = g_new0(Options, 1);
-    /* don't go anywhere if theres no options given */
+static gpointer setup_go_last_func(ObParseInst *i, xmlDocPtr doc,
+                                   xmlNodePtr node)
+{
+    Options *o = g_new0(Options, 1);
+    o->type = LAST;
+    return o;
+}
+
+static gpointer setup_send_last_func(ObParseInst *i, xmlDocPtr doc,
+                                     xmlNodePtr node)
+{
+    Options *o = setup_follow(i, doc, node);
+    o->type = LAST;
+    return o;
+}
+
+static gpointer setup_go_abs_func(ObParseInst *i, xmlDocPtr doc,
+                                   xmlNodePtr node)
+{
+    xmlNodePtr n;
+    Options *o = g_new0(Options, 1);
     o->type = ABSOLUTE;
-    o->u.abs.desktop = screen_desktop;
-    /* wrap by default - it's handy! */
-    o->u.rel.wrap = TRUE;
+    if ((n = parse_find_node("desktop", node)))
+        o->u.abs.desktop = parse_int(doc, n) - 1;
+    else
+        o->u.abs.desktop = screen_desktop;
+    return o;
+}
 
-    if ((n = parse_find_node("to", node))) {
-        gchar *s = parse_string(doc, n);
-        if (!g_ascii_strcasecmp(s, "last"))
-            o->type = LAST;
-        else if (!g_ascii_strcasecmp(s, "next")) {
-            o->type = RELATIVE;
-            o->u.rel.linear = TRUE;
-            o->u.rel.dir = OB_DIRECTION_EAST;
-        }
-        else if (!g_ascii_strcasecmp(s, "previous")) {
-            o->type = RELATIVE;
-            o->u.rel.linear = TRUE;
-            o->u.rel.dir = OB_DIRECTION_WEST;
-        }
-        else if (!g_ascii_strcasecmp(s, "north") ||
-                 !g_ascii_strcasecmp(s, "up")) {
-            o->type = RELATIVE;
-            o->u.rel.dir = OB_DIRECTION_NORTH;
-        }
-        else if (!g_ascii_strcasecmp(s, "south") ||
-                 !g_ascii_strcasecmp(s, "down")) {
-            o->type = RELATIVE;
-            o->u.rel.dir = OB_DIRECTION_SOUTH;
-        }
-        else if (!g_ascii_strcasecmp(s, "west") ||
-                 !g_ascii_strcasecmp(s, "left")) {
-            o->type = RELATIVE;
-            o->u.rel.dir = OB_DIRECTION_WEST;
-        }
-        else if (!g_ascii_strcasecmp(s, "east") ||
-                 !g_ascii_strcasecmp(s, "right")) {
-            o->type = RELATIVE;
-            o->u.rel.dir = OB_DIRECTION_EAST;
-        }
-        else {
-            o->type = ABSOLUTE;
-            o->u.abs.desktop = atoi(s) - 1;
-        }
-        g_free(s);
-    }
+static gpointer setup_send_abs_func(ObParseInst *i, xmlDocPtr doc,
+                                     xmlNodePtr node)
+{
+    xmlNodePtr n;
+    Options *o = setup_follow(i, doc, node);
+    o->type = ABSOLUTE;
+    if ((n = parse_find_node("desktop", node)))
+        o->u.abs.desktop = parse_int(doc, n) - 1;
+    else
+        o->u.abs.desktop = screen_desktop;
+    return o;
+}
+
+static void setup_rel(Options *o, ObParseInst *i, xmlDocPtr doc,
+                      xmlNodePtr node, gboolean lin, ObDirection dir)
+{
+    xmlNodePtr n;
+
+    o->type = RELATIVE;
+    o->u.rel.linear = lin;
+    o->u.rel.dir = dir;
+    o->u.rel.wrap = TRUE;
 
     if ((n = parse_find_node("wrap", node)))
         o->u.rel.wrap = parse_bool(doc, n);
+}
 
+static gpointer setup_go_next_func(ObParseInst *i, xmlDocPtr doc,
+                                   xmlNodePtr node)
+{
+    Options *o = g_new0(Options, 1);
+    setup_rel(o, i, doc, node, TRUE, OB_DIRECTION_EAST);
     return o;
 }
 
-static gpointer setup_send_func(ObParseInst *i, xmlDocPtr doc,
-                                xmlNodePtr node)
+static gpointer setup_send_next_func(ObParseInst *i, xmlDocPtr doc,
+                                     xmlNodePtr node)
 {
-    xmlNodePtr n;
-    Options *o;
+    Options *o = setup_follow(i, doc, node);
+    setup_rel(o, i, doc, node, TRUE, OB_DIRECTION_EAST);
+    return o;
+}
 
-    o = setup_go_func(i, doc, node);
-    o->send = TRUE;
-    o->follow = TRUE;
+static gpointer setup_go_prev_func(ObParseInst *i, xmlDocPtr doc,
+                                   xmlNodePtr node)
+{
+    Options *o = g_new0(Options, 1);
+    setup_rel(o, i, doc, node, TRUE, OB_DIRECTION_WEST);
+    return o;
+}
 
-    if ((n = parse_find_node("follow", node)))
-        o->follow = parse_bool(doc, n);
+static gpointer setup_send_prev_func(ObParseInst *i, xmlDocPtr doc,
+                                     xmlNodePtr node)
+{
+    Options *o = setup_follow(i, doc, node);
+    setup_rel(o, i, doc, node, TRUE, OB_DIRECTION_WEST);
+    return o;
+}
+
+static gpointer setup_go_left_func(ObParseInst *i, xmlDocPtr doc,
+                                   xmlNodePtr node)
+{
+    Options *o = g_new0(Options, 1);
+    setup_rel(o, i, doc, node, FALSE, OB_DIRECTION_WEST);
+    return o;
+}
+
+static gpointer setup_send_left_func(ObParseInst *i, xmlDocPtr doc,
+                                     xmlNodePtr node)
+{
+    Options *o = setup_follow(i, doc, node);
+    setup_rel(o, i, doc, node, FALSE, OB_DIRECTION_WEST);
+    return o;
+}
+
+static gpointer setup_go_right_func(ObParseInst *i, xmlDocPtr doc,
+                                    xmlNodePtr node)
+{
+    Options *o = g_new0(Options, 1);
+    setup_rel(o, i, doc, node, FALSE, OB_DIRECTION_EAST);
+    return o;
+}
+
+static gpointer setup_send_right_func(ObParseInst *i, xmlDocPtr doc,
+                                      xmlNodePtr node)
+{
+    Options *o = setup_follow(i, doc, node);
+    setup_rel(o, i, doc, node, FALSE, OB_DIRECTION_EAST);
+    return o;
+}
+
+static gpointer setup_go_up_func(ObParseInst *i, xmlDocPtr doc,
+                                 xmlNodePtr node)
+{
+    Options *o = g_new0(Options, 1);
+    setup_rel(o, i, doc, node, FALSE, OB_DIRECTION_NORTH);
+    return o;
+}
+
+static gpointer setup_send_up_func(ObParseInst *i, xmlDocPtr doc,
+                                   xmlNodePtr node)
+{
+    Options *o = setup_follow(i, doc, node);
+    setup_rel(o, i, doc, node, FALSE, OB_DIRECTION_NORTH);
+    return o;
+}
 
+static gpointer setup_go_down_func(ObParseInst *i, xmlDocPtr doc,
+                                   xmlNodePtr node)
+{
+    Options *o = g_new0(Options, 1);
+    setup_rel(o, i, doc, node, FALSE, OB_DIRECTION_SOUTH);
+    return o;
+}
+
+static gpointer setup_send_down_func(ObParseInst *i, xmlDocPtr doc,
+                                     xmlNodePtr node)
+{
+    Options *o = setup_follow(i, doc, node);
+    setup_rel(o, i, doc, node, FALSE, OB_DIRECTION_SOUTH);
     return o;
 }
 
index 6559e44..a9b896d 100644 (file)
@@ -4,6 +4,7 @@
 #include "openbox/window.h"
 #include "openbox/focus_cycle.h"
 #include "openbox/openbox.h"
+#include "openbox/client.h"
 #include "openbox/misc.h"
 #include "gettext.h"
 
@@ -21,10 +22,38 @@ typedef struct {
 static gboolean cycling = FALSE;
 
 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
-static gpointer setup_cycle_func(ObParseInst *i, xmlDocPtr doc,
-                                 xmlNodePtr node);
-static gpointer setup_target_func(ObParseInst *i, xmlDocPtr doc,
-                                  xmlNodePtr node);
+static gpointer setup_north_cycle_func(ObParseInst *i,
+                                       xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_south_cycle_func(ObParseInst *i,
+                                       xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_east_cycle_func(ObParseInst *i,
+                                      xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_west_cycle_func(ObParseInst *i,
+                                      xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_northwest_cycle_func(ObParseInst *i,
+                                           xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_northeast_cycle_func(ObParseInst *i,
+                                           xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_southwest_cycle_func(ObParseInst *i,
+                                           xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_southeast_cycle_func(ObParseInst *i,
+                                           xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_north_target_func(ObParseInst *i,
+                                        xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_south_target_func(ObParseInst *i,
+                                        xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_east_target_func(ObParseInst *i,
+                                       xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_west_target_func(ObParseInst *i,
+                                       xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_northwest_target_func(ObParseInst *i,
+                                            xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_northeast_target_func(ObParseInst *i,
+                                            xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_southwest_target_func(ObParseInst *i,
+                                            xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_southeast_target_func(ObParseInst *i,
+                                            xmlDocPtr doc, xmlNodePtr node);
 static void     free_func(gpointer options);
 static gboolean run_func(ObActionsData *data, gpointer options);
 static gboolean i_input_func(guint initial_state,
@@ -37,10 +66,38 @@ static void     end_cycle(gboolean cancel, guint state, Options *o);
 
 void action_directionalwindows_startup(void)
 {
-    actions_register("DirectionalCycleWindows", setup_cycle_func, free_func,
-                     run_func, i_input_func, i_cancel_func);
-    actions_register("DirectionalTargetWindow", setup_target_func, free_func,
-                     run_func, NULL, NULL);
+    actions_register("DirectionalFocusNorth", setup_north_cycle_func,
+                     free_func, run_func, i_input_func, i_cancel_func);
+    actions_register("DirectionalFocusSouth", setup_south_cycle_func,
+                     free_func, run_func, i_input_func, i_cancel_func);
+    actions_register("DirectionalFocusWest", setup_west_cycle_func,
+                     free_func, run_func, i_input_func, i_cancel_func);
+    actions_register("DirectionalFocusEast", setup_east_cycle_func,
+                     free_func, run_func, i_input_func, i_cancel_func);
+    actions_register("DirectionalFocusNorthWest", setup_northwest_cycle_func,
+                     free_func, run_func, i_input_func, i_cancel_func);
+    actions_register("DirectionalFocusNorthEast", setup_northeast_cycle_func,
+                     free_func, run_func, i_input_func, i_cancel_func);
+    actions_register("DirectionalFocusSouthWest", setup_southwest_cycle_func,
+                     free_func, run_func, i_input_func, i_cancel_func);
+    actions_register("DirectionalFocusSouthEast", setup_southeast_cycle_func,
+                     free_func, run_func, i_input_func, i_cancel_func);
+    actions_register("DirectionalTargetNorth", setup_north_target_func,
+                     free_func, run_func, i_input_func, i_cancel_func);
+    actions_register("DirectionalTargetSouth", setup_south_target_func,
+                     free_func, run_func, i_input_func, i_cancel_func);
+    actions_register("DirectionalTargetWest", setup_west_target_func,
+                     free_func, run_func, i_input_func, i_cancel_func);
+    actions_register("DirectionalTargetEast", setup_east_target_func,
+                     free_func, run_func, i_input_func, i_cancel_func);
+    actions_register("DirectionalTargetNorthWest", setup_northwest_target_func,
+                     free_func, run_func, i_input_func, i_cancel_func);
+    actions_register("DirectionalTargetNorthEast", setup_northeast_target_func,
+                     free_func, run_func, i_input_func, i_cancel_func);
+    actions_register("DirectionalTargetSouthWest", setup_southwest_target_func,
+                     free_func, run_func, i_input_func, i_cancel_func);
+    actions_register("DirectionalTargetSouthEast", setup_southeast_target_func,
+                     free_func, run_func, i_input_func, i_cancel_func);
 }
 
 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
@@ -62,30 +119,6 @@ static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
         o->dock_windows = parse_bool(doc, n);
     if ((n = parse_find_node("desktop", node)))
         o->desktop_windows = parse_bool(doc, n);
-    if ((n = parse_find_node("direction", node))) {
-        gchar *s = parse_string(doc, n);
-        if (!g_ascii_strcasecmp(s, "north") ||
-            !g_ascii_strcasecmp(s, "up"))
-            o->direction = OB_DIRECTION_NORTH;
-        else if (!g_ascii_strcasecmp(s, "northwest"))
-            o->direction = OB_DIRECTION_NORTHWEST;
-        else if (!g_ascii_strcasecmp(s, "northeast"))
-            o->direction = OB_DIRECTION_NORTHEAST;
-        else if (!g_ascii_strcasecmp(s, "west") ||
-                 !g_ascii_strcasecmp(s, "left"))
-            o->direction = OB_DIRECTION_WEST;
-        else if (!g_ascii_strcasecmp(s, "east") ||
-                 !g_ascii_strcasecmp(s, "right"))
-            o->direction = OB_DIRECTION_EAST;
-        else if (!g_ascii_strcasecmp(s, "south") ||
-                 !g_ascii_strcasecmp(s, "down"))
-            o->direction = OB_DIRECTION_SOUTH;
-        else if (!g_ascii_strcasecmp(s, "southwest"))
-            o->direction = OB_DIRECTION_SOUTHWEST;
-        else if (!g_ascii_strcasecmp(s, "southeast"))
-            o->direction = OB_DIRECTION_SOUTHEAST;
-        g_free(s);
-    }
 
     if ((n = parse_find_node("finalactions", node))) {
         xmlNodePtr m;
@@ -109,19 +142,147 @@ static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
     return o;
 }
 
-static gpointer setup_cycle_func(ObParseInst *i, xmlDocPtr doc,
-                                 xmlNodePtr node)
+static gpointer setup_north_cycle_func(ObParseInst *i,
+                                       xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->interactive = TRUE;
+    o->direction = OB_DIRECTION_NORTH;
+    return o;
+}
+
+static gpointer setup_south_cycle_func(ObParseInst *i,
+                                       xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->interactive = TRUE;
+    o->direction = OB_DIRECTION_SOUTH;
+    return o;
+}
+
+static gpointer setup_east_cycle_func(ObParseInst *i,
+                                      xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->interactive = TRUE;
+    o->direction = OB_DIRECTION_EAST;
+    return o;
+}
+
+static gpointer setup_west_cycle_func(ObParseInst *i,
+                                      xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->interactive = TRUE;
+    o->direction = OB_DIRECTION_WEST;
+    return o;
+}
+
+static gpointer setup_northwest_cycle_func(ObParseInst *i,
+                                           xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->interactive = TRUE;
+    o->direction = OB_DIRECTION_NORTHWEST;
+    return o;
+}
+
+static gpointer setup_northeast_cycle_func(ObParseInst *i,
+                                           xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->interactive = TRUE;
+    o->direction = OB_DIRECTION_EAST;
+    return o;
+}
+
+static gpointer setup_southwest_cycle_func(ObParseInst *i,
+                                           xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->interactive = TRUE;
+    o->direction = OB_DIRECTION_SOUTHWEST;
+    return o;
+}
+
+static gpointer setup_southeast_cycle_func(ObParseInst *i,
+                                           xmlDocPtr doc, xmlNodePtr node)
 {
     Options *o = setup_func(i, doc, node);
     o->interactive = TRUE;
+    o->direction = OB_DIRECTION_SOUTHEAST;
+    return o;
+}
+
+static gpointer setup_north_target_func(ObParseInst *i,
+                                        xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->interactive = FALSE;
+    o->direction = OB_DIRECTION_NORTH;
+    return o;
+}
+
+static gpointer setup_south_target_func(ObParseInst *i,
+                                        xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->interactive = FALSE;
+    o->direction = OB_DIRECTION_SOUTH;
+    return o;
+}
+
+static gpointer setup_east_target_func(ObParseInst *i,
+                                       xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->interactive = FALSE;
+    o->direction = OB_DIRECTION_EAST;
+    return o;
+}
+
+static gpointer setup_west_target_func(ObParseInst *i,
+                                       xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->interactive = FALSE;
+    o->direction = OB_DIRECTION_WEST;
+    return o;
+}
+
+static gpointer setup_northwest_target_func(ObParseInst *i,
+                                            xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->interactive = FALSE;
+    o->direction = OB_DIRECTION_NORTHWEST;
+    return o;
+}
+
+static gpointer setup_northeast_target_func(ObParseInst *i,
+                                            xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->interactive = FALSE;
+    o->direction = OB_DIRECTION_NORTHEAST;
+    return o;
+}
+
+static gpointer setup_southwest_target_func(ObParseInst *i,
+                                            xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->interactive = FALSE;
+    o->direction = OB_DIRECTION_SOUTHWEST;
     return o;
 }
 
-static gpointer setup_target_func(ObParseInst *i, xmlDocPtr doc,
-                                  xmlNodePtr node)
+static gpointer setup_southeast_target_func(ObParseInst *i,
+                                            xmlDocPtr doc, xmlNodePtr node)
 {
     Options *o = setup_func(i, doc, node);
     o->interactive = FALSE;
+    o->direction = OB_DIRECTION_SOUTHEAST;
     return o;
 }
 
index cb3ab24..29cd327 100644 (file)
@@ -1,4 +1,5 @@
 #include "openbox/actions.h"
+#include "openbox/client.h"
 #include "openbox/event.h"
 #include "openbox/startupnotify.h"
 #include "openbox/prompt.h"
@@ -16,18 +17,16 @@ typedef struct {
     gchar   *sn_icon;
     gchar   *sn_wmclass;
     gchar   *prompt;
+    ObActionsData *data;
 } Options;
 
 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
 static void     free_func(gpointer options);
 static gboolean run_func(ObActionsData *data, gpointer options);
-/*
-static gboolean i_input_func(guint initial_state,
-                             XEvent *e,
-                             gpointer options,
-                             gboolean *used);
-static void     i_cancel_func(gpointer options);
-*/
+static void shutdown_func(void);
+static void client_dest(ObClient *client, gpointer data);
+
+static GSList *prompt_opts = NULL;
 
 void action_execute_startup(void)
 {
@@ -36,6 +35,20 @@ void action_execute_startup(void)
                      free_func,
                      run_func,
                      NULL, NULL);
+    actions_set_shutdown("Execute", shutdown_func);
+
+    client_add_destroy_notify(client_dest, NULL);
+}
+
+static void client_dest(ObClient *client, gpointer data)
+{
+    GSList *it;
+
+    for (it = prompt_opts; it; it = g_slist_next(it)) {
+        Options *o = it->data;
+        if (o->data->client == client)
+            o->data->client = NULL;
+    }
 }
 
 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
@@ -70,21 +83,29 @@ static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
     return o;
 }
 
+static void shutdown_func(void)
+{
+    client_remove_destroy_notify(client_dest);
+}
+
 static void free_func(gpointer options)
 {
     Options *o = options;
 
     if (o) {
+        prompt_opts = g_slist_remove(prompt_opts, o);
+
         g_free(o->cmd);
         g_free(o->sn_name);
         g_free(o->sn_icon);
         g_free(o->sn_wmclass);
         g_free(o->prompt);
+        if (o->data) g_free(o->data);
         g_free(o);
     }
 }
 
-static Options* dup_options(Options *in)
+static Options* dup_options(Options *in, ObActionsData *data)
 {
     Options *o = g_new(Options, 1);
     o->cmd = g_strdup(in->cmd);
@@ -93,15 +114,15 @@ static Options* dup_options(Options *in)
     o->sn_icon = g_strdup(in->sn_icon);
     o->sn_wmclass = g_strdup(in->sn_wmclass);
     o->prompt = NULL;
+    o->data = g_memdup(data, sizeof(ObActionsData));
     return o;
 }
 
-static gboolean run_func(ObActionsData *data, gpointer options);
-
 static gboolean prompt_cb(ObPrompt *p, gint result, gpointer options)
 {
+    Options *o = options;
     if (result)
-        run_func(NULL, options);
+        run_func(o->data, o);
     return TRUE; /* call the cleanup func */
 }
 
@@ -129,7 +150,7 @@ static gboolean run_func(ObActionsData *data, gpointer options)
             { _("Yes"), 1 }
         };
 
-        ocp = dup_options(options);
+        ocp = dup_options(options, data);
         p = prompt_new(o->prompt, _("Execute"), answers, 2, 0, 0,
                        prompt_cb, prompt_cleanup, ocp);
         prompt_show(p, NULL, FALSE);
@@ -145,10 +166,11 @@ static gboolean run_func(ObActionsData *data, gpointer options)
 
     /* If there is a keyboard grab going on then we need to cancel
        it so the application can grab things */
-    event_cancel_all_key_grabs();
+    if (data->uact != OB_USER_ACTION_MENU_SELECTION)
+        event_cancel_all_key_grabs();
 
     if (!g_shell_parse_argv(cmd, NULL, &argv, &e)) {
-        g_message(e->message, o->cmd);
+        g_message("%s", e->message);
         g_error_free(e);
     }
     else {
@@ -167,7 +189,7 @@ static gboolean run_func(ObActionsData *data, gpointer options)
                            G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
                            NULL, NULL, NULL, &e))
         {
-            g_message(e->message, o->cmd);
+            g_message("%s", e->message);
             g_error_free(e);
 
             if (o->sn)
index 567926e..f447830 100644 (file)
@@ -10,11 +10,12 @@ typedef struct {
 
 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
 static gboolean run_func(ObActionsData *data, gpointer options);
+static void free_func(gpointer options);
 
 void action_exit_startup(void)
 {
-    actions_register("Exit", setup_func, NULL, run_func, NULL, NULL);
-    actions_register("SessionLogout", setup_func, NULL, run_func, NULL, NULL);
+    actions_register("Exit", setup_func, free_func, run_func, NULL, NULL);
+    actions_register("SessionLogout", setup_func, free_func, run_func, NULL, NULL);
 }
 
 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
@@ -31,6 +32,12 @@ static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
     return o;
 }
 
+static void free_func(gpointer options)
+{
+    if (options)
+        g_free(options);
+}
+
 static void do_exit(void)
 {
     if (session_connected())
index 1b54491..be5de2f 100644 (file)
@@ -6,10 +6,13 @@
 
 typedef struct {
     gboolean here;
+    gboolean activate;
     gboolean stop_int;
 } Options;
 
 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_activate_func(ObParseInst *i,
+                                    xmlDocPtr doc, xmlNodePtr node);
 static void     free_func(gpointer options);
 static gboolean run_func(ObActionsData *data, gpointer options);
 
@@ -20,6 +23,11 @@ void action_focus_startup(void)
                      free_func,
                      run_func,
                      NULL, NULL);
+    actions_register("Activate",
+                     setup_activate_func,
+                     free_func,
+                     run_func,
+                     NULL, NULL);
 }
 
 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
@@ -37,6 +45,14 @@ static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
     return o;
 }
 
+static gpointer setup_activate_func(ObParseInst *i,
+                                    xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->activate = TRUE;
+    return o;
+}
+
 static void free_func(gpointer options)
 {
     Options *o = options;
@@ -64,7 +80,8 @@ static gboolean run_func(ObActionsData *data, gpointer options)
                 actions_interactive_cancel_act();
 
             actions_client_move(data, TRUE);
-            client_activate(data->client, TRUE, o->here, FALSE, FALSE, TRUE);
+            client_activate(data->client, TRUE, o->here,
+                            o->activate, o->activate, TRUE);
             actions_client_move(data, FALSE);
         }
     } else if (data->context == OB_FRAME_CONTEXT_DESKTOP) {
index 69b8ef7..a18390d 100644 (file)
@@ -9,52 +9,58 @@ typedef struct {
     ObDirection dir;
 } Options;
 
-static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
-static void     free_func(gpointer options);
+static gpointer setup_north_func(ObParseInst *i,
+                                 xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_south_func(ObParseInst *i,
+                                 xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_east_func(ObParseInst *i,
+                                xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_west_func(ObParseInst *i,
+                                xmlDocPtr doc, xmlNodePtr node);
 static gboolean run_func(ObActionsData *data, gpointer options);
 
 void action_growtoedge_startup(void)
 {
-    actions_register("GrowToEdge",
-                     setup_func,
-                     free_func,
-                     run_func,
+    actions_register("GrowToEdgeNorth", setup_north_func, g_free, run_func,
+                     NULL, NULL);
+    actions_register("GrowToEdgeSouth", setup_south_func, g_free, run_func,
+                     NULL, NULL);
+    actions_register("GrowToEdgeEast", setup_east_func, g_free, run_func,
+                     NULL, NULL);
+    actions_register("GrowToEdgeWest", setup_west_func, g_free, run_func,
                      NULL, NULL);
 }
 
-static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
+static gpointer setup_north_func(ObParseInst *i,
+                                 xmlDocPtr doc, xmlNodePtr node)
 {
-    xmlNodePtr n;
-    Options *o;
-
-    o = g_new0(Options, 1);
+    Options *o = g_new0(Options, 1);
     o->dir = OB_DIRECTION_NORTH;
+    return o;
+}
 
-    if ((n = parse_find_node("direction", node))) {
-        gchar *s = parse_string(doc, n);
-        if (!g_ascii_strcasecmp(s, "north") ||
-            !g_ascii_strcasecmp(s, "up"))
-            o->dir = OB_DIRECTION_NORTH;
-        else if (!g_ascii_strcasecmp(s, "south") ||
-                 !g_ascii_strcasecmp(s, "down"))
-            o->dir = OB_DIRECTION_SOUTH;
-        else if (!g_ascii_strcasecmp(s, "west") ||
-                 !g_ascii_strcasecmp(s, "left"))
-            o->dir = OB_DIRECTION_WEST;
-        else if (!g_ascii_strcasecmp(s, "east") ||
-                 !g_ascii_strcasecmp(s, "right"))
-            o->dir = OB_DIRECTION_EAST;
-        g_free(s);
-    }
-
+static gpointer setup_south_func(ObParseInst *i,
+                                 xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = g_new0(Options, 1);
+    o->dir = OB_DIRECTION_SOUTH;
     return o;
 }
 
-static void free_func(gpointer options)
+static gpointer setup_east_func(ObParseInst *i,
+                                xmlDocPtr doc, xmlNodePtr node)
 {
-    Options *o = options;
+    Options *o = g_new0(Options, 1);
+    o->dir = OB_DIRECTION_EAST;
+    return o;
+}
 
-    g_free(o);
+static gpointer setup_west_func(ObParseInst *i,
+                                xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = g_new0(Options, 1);
+    o->dir = OB_DIRECTION_WEST;
+    return o;
 }
 
 static gboolean do_grow(ObActionsData *data, gint x, gint y, gint w, gint h)
diff --git a/openbox/actions/if.c b/openbox/actions/if.c
deleted file mode 100644 (file)
index 4c98966..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-#include "openbox/actions.h"
-#include "openbox/misc.h"
-#include "openbox/client.h"
-#include "openbox/frame.h"
-#include "openbox/screen.h"
-#include "openbox/focus.h"
-#include <glib.h>
-
-typedef struct {
-    gboolean shaded_on;
-    gboolean shaded_off;
-    gboolean maxvert_on;
-    gboolean maxvert_off;
-    gboolean maxhorz_on;
-    gboolean maxhorz_off;
-    gboolean maxfull_on;
-    gboolean maxfull_off;
-    gboolean iconic_on;
-    gboolean iconic_off;
-    gboolean focused;
-    gboolean unfocused;
-    GSList *thenacts;
-    GSList *elseacts;
-} Options;
-
-static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
-static void     free_func(gpointer options);
-static gboolean run_func(ObActionsData *data, gpointer options);
-
-void action_if_startup(void)
-{
-    actions_register("If",
-                     setup_func,
-                     free_func,
-                     run_func,
-                     NULL, NULL);
-}
-
-static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
-{
-    xmlNodePtr n;
-    Options *o;
-
-    o = g_new0(Options, 1);
-
-    if ((n = parse_find_node("shaded", node))) {
-        if (parse_bool(doc, n))
-            o->shaded_on = TRUE;
-        else
-            o->shaded_off = TRUE;
-    }
-    if ((n = parse_find_node("maximized", node))) {
-        if (parse_bool(doc, n))
-            o->maxfull_on = TRUE;
-        else
-            o->maxfull_off = TRUE;
-    }
-    if ((n = parse_find_node("maximizedhorizontal", node))) {
-        if (parse_bool(doc, n))
-            o->maxhorz_on = TRUE;
-        else
-            o->maxhorz_off = TRUE;
-    }
-    if ((n = parse_find_node("maximizedvertical", node))) {
-        if (parse_bool(doc, n))
-            o->maxvert_on = TRUE;
-        else
-            o->maxvert_off = TRUE;
-    }
-    if ((n = parse_find_node("iconified", node))) {
-        if (parse_bool(doc, n))
-            o->iconic_on = TRUE;
-        else
-            o->iconic_off = TRUE;
-    }
-    if ((n = parse_find_node("focused", node))) {
-        if (parse_bool(doc, n))
-            o->focused = TRUE;
-        else
-            o->unfocused = TRUE;
-    }
-
-    if ((n = parse_find_node("then", node))) {
-        xmlNodePtr m;
-
-        m = parse_find_node("action", n->xmlChildrenNode);
-        while (m) {
-            ObActionsAct *action = actions_parse(i, doc, m);
-            if (action) o->thenacts = g_slist_append(o->thenacts, action);
-            m = parse_find_node("action", m->next);
-        }
-    }
-    if ((n = parse_find_node("else", node))) {
-        xmlNodePtr m;
-
-        m = parse_find_node("action", n->xmlChildrenNode);
-        while (m) {
-            ObActionsAct *action = actions_parse(i, doc, m);
-            if (action) o->elseacts = g_slist_append(o->elseacts, action);
-            m = parse_find_node("action", m->next);
-        }
-    }
-
-    return o;
-}
-
-static void free_func(gpointer options)
-{
-    Options *o = options;
-
-    g_free(o);
-}
-
-/* Always return FALSE because its not interactive */
-static gboolean run_func(ObActionsData *data, gpointer options)
-{
-    Options *o = options;
-    GSList *acts;
-    ObClient *c = data->client;
-
-    if ((!o->shaded_on || (c && c->shaded)) &&
-        (!o->shaded_off || (c && !c->shaded)) &&
-        (!o->iconic_on || (c && c->iconic)) &&
-        (!o->iconic_off || (c && !c->iconic)) &&
-        (!o->maxhorz_on || (c && c->max_horz)) &&
-        (!o->maxhorz_off || (c && !c->max_horz)) &&
-        (!o->maxvert_on || (c && c->max_vert)) &&
-        (!o->maxvert_off || (c && !c->max_vert)) &&
-        (!o->maxfull_on || (c && c->max_vert && c->max_horz)) &&
-        (!o->maxfull_off || (c && !(c->max_vert && c->max_horz))) &&
-        (!o->focused || (c && (c == focus_client))) &&
-        (!o->unfocused || (c && !(c == focus_client))))
-    {
-        acts = o->thenacts;
-    }
-    else
-        acts = o->elseacts;
-
-    actions_run_acts(acts, data->uact, data->state,
-                     data->x, data->y, data->button,
-                     data->context, data->client);
-
-    return FALSE;
-}
index 92fa480..6a8e698 100644 (file)
@@ -9,8 +9,12 @@ typedef struct {
 static gpointer setup_func_top(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
 static gpointer setup_func_bottom(ObParseInst *i, xmlDocPtr doc,
                                   xmlNodePtr node);
-static gpointer setup_func_send(ObParseInst *i, xmlDocPtr doc,
-                                xmlNodePtr node);
+static gpointer setup_sendtop_func(ObParseInst *i,
+                                     xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_sendbottom_func(ObParseInst *i,
+                                        xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_sendnormal_func(ObParseInst *i,
+                                      xmlDocPtr doc, xmlNodePtr node);
 static gboolean run_func(ObActionsData *data, gpointer options);
 
 void action_layer_startup(void)
@@ -19,7 +23,11 @@ void action_layer_startup(void)
                      run_func, NULL, NULL);
     actions_register("ToggleAlwaysOnBottom", setup_func_bottom, g_free,
                      run_func, NULL, NULL);
-    actions_register("SendToLayer", setup_func_send, g_free,
+    actions_register("SendToTopLayer", setup_sendtop_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("SendToBottomLayer", setup_sendbottom_func, g_free,
+                     run_func, NULL, NULL);
+    actions_register("SendToNormalLayer", setup_sendnormal_func, g_free,
                      run_func, NULL, NULL);
 }
 
@@ -40,28 +48,30 @@ static gpointer setup_func_bottom(ObParseInst *i, xmlDocPtr doc,
     return o;
 }
 
-static gpointer setup_func_send(ObParseInst *i, xmlDocPtr doc,
-                                xmlNodePtr node)
+static gpointer setup_sendtop_func(ObParseInst *i,
+                                     xmlDocPtr doc, xmlNodePtr node)
 {
-    xmlNodePtr n;
-    Options *o;
-
-    o = g_new0(Options, 1);
+    Options *o = g_new0(Options, 1);
+    o->layer = 1;
+    o->toggle = FALSE;
+    return o;
+}
 
-    if ((n = parse_find_node("layer", node))) {
-        gchar *s = parse_string(doc, n);
-        if (!g_ascii_strcasecmp(s, "above") ||
-            !g_ascii_strcasecmp(s, "top"))
-            o->layer = 1;
-        else if (!g_ascii_strcasecmp(s, "below") ||
-                 !g_ascii_strcasecmp(s, "bottom"))
-            o->layer = -1;
-        else if (!g_ascii_strcasecmp(s, "normal") ||
-                 !g_ascii_strcasecmp(s, "middle"))
-            o->layer = 0;
-        g_free(s);
-    }
+static gpointer setup_sendbottom_func(ObParseInst *i,
+                                        xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = g_new0(Options, 1);
+    o->layer = -1;
+    o->toggle = FALSE;
+    return o;
+}
 
+static gpointer setup_sendnormal_func(ObParseInst *i,
+                                      xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = g_new0(Options, 1);
+    o->layer = 0;
+    o->toggle = FALSE;
     return o;
 }
 
index bb6f470..fa896ed 100644 (file)
@@ -12,40 +12,56 @@ typedef struct {
     MaxDirection dir;
 } Options;
 
-static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_both_func(ObParseInst *i, xmlDocPtr doc,
+                              xmlNodePtr node);
+static gpointer setup_horz_func(ObParseInst *i, xmlDocPtr doc,
+                               xmlNodePtr node);
+static gpointer setup_vert_func(ObParseInst *i,
+                                  xmlDocPtr doc, xmlNodePtr node);
 static gboolean run_func_on(ObActionsData *data, gpointer options);
 static gboolean run_func_off(ObActionsData *data, gpointer options);
 static gboolean run_func_toggle(ObActionsData *data, gpointer options);
 
 void action_maximize_startup(void)
 {
-    actions_register("Maximize", setup_func, g_free, run_func_on,
-                     NULL, NULL);
-    actions_register("Unmaximize", setup_func, g_free, run_func_off,
-                     NULL, NULL);
-    actions_register("ToggleMaximize", setup_func, g_free, run_func_toggle,
-                     NULL, NULL);
+    actions_register("MaximizeFull", setup_both_func, g_free,
+                     run_func_on, NULL, NULL);
+    actions_register("UnmaximizeFull", setup_both_func, g_free,
+                     run_func_off, NULL, NULL);
+    actions_register("ToggleMaximizeFull", setup_both_func, g_free,
+                     run_func_toggle, NULL, NULL);
+    actions_register("MaximizeHorz", setup_horz_func, g_free,
+                     run_func_on, NULL, NULL);
+    actions_register("UnmaximizeHorz", setup_horz_func, g_free,
+                     run_func_off, NULL, NULL);
+    actions_register("ToggleMaximizeHorz", setup_horz_func, g_free,
+                     run_func_toggle, NULL, NULL);
+    actions_register("MaximizeVert", setup_vert_func, g_free,
+                     run_func_on, NULL, NULL);
+    actions_register("UnmaximizeVert", setup_vert_func, g_free,
+                     run_func_off, NULL, NULL);
+    actions_register("ToggleMaximizeVert", setup_vert_func, g_free,
+                     run_func_toggle, NULL, NULL);
 }
 
-static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
+static gpointer setup_both_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
 {
-    xmlNodePtr n;
-    Options *o;
-
-    o = g_new0(Options, 1);
+    Options *o = g_new0(Options, 1);
     o->dir = BOTH;
+    return o;
+}
 
-    if ((n = parse_find_node("direction", node))) {
-        gchar *s = parse_string(doc, n);
-        if (!g_ascii_strcasecmp(s, "vertical") ||
-            !g_ascii_strcasecmp(s, "vert"))
-            o->dir = VERT;
-        else if (!g_ascii_strcasecmp(s, "horizontal") ||
-                 !g_ascii_strcasecmp(s, "horz"))
-            o->dir = HORZ;
-        g_free(s);
-    }
+static gpointer setup_horz_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = g_new0(Options, 1);
+    o->dir = HORZ;
+    return o;
+}
 
+static gpointer setup_vert_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = g_new0(Options, 1);
+    o->dir = VERT;
     return o;
 }
 
index 1d1189c..a553519 100644 (file)
@@ -54,15 +54,15 @@ static gboolean run_func(ObActionsData *data, gpointer options)
         gint x, y, lw, lh, w, h;
 
         c = data->client;
-        x = data->client->area.x + o->x;
-        y = data->client->area.y + o->y;
-        w = data->client->area.width;
-        h = data->client->area.height;
-        client_try_configure(data->client, &x, &y, &w, &h, &lw, &lh, TRUE);
-        client_find_onscreen(data->client, &x, &y, w, h, FALSE);
+        x = c->area.x + o->x;
+        y = c->area.y + o->y;
+        w = c->area.width;
+        h = c->area.height;
+        client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE);
+        client_find_onscreen(c, &x, &y, w, h, FALSE);
 
         actions_client_move(data, TRUE);
-        client_configure(data->client, x, y, w, h, TRUE, TRUE, FALSE);
+        client_configure(c, x, y, w, h, TRUE, TRUE, FALSE);
         actions_client_move(data, FALSE);
     }
 
index 29780c4..da66e1b 100644 (file)
@@ -24,6 +24,8 @@ typedef struct {
 } Options;
 
 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_center_func(ObParseInst *i, xmlDocPtr doc,
+                                  xmlNodePtr node);
 static void     free_func(gpointer options);
 static gboolean run_func(ObActionsData *data, gpointer options);
 
@@ -34,6 +36,11 @@ void action_moveresizeto_startup(void)
                      free_func,
                      run_func,
                      NULL, NULL);
+    actions_register("MoveToCenter",
+                     setup_center_func,
+                     free_func,
+                     run_func,
+                     NULL, NULL);
 }
 
 static void parse_coord(xmlDocPtr doc, xmlNodePtr n, gint *pos,
@@ -104,6 +111,22 @@ static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
     return o;
 }
 
+static gpointer setup_center_func(ObParseInst *i, xmlDocPtr doc,
+                                  xmlNodePtr node)
+{
+    Options *o;
+
+    o = g_new0(Options, 1);
+    o->x = G_MININT;
+    o->y = G_MININT;
+    o->w = G_MININT;
+    o->h = G_MININT;
+    o->monitor = -1;
+    o->xcenter = TRUE;
+    o->ycenter = TRUE;
+    return o;
+}
+
 static void free_func(gpointer options)
 {
     Options *o = options;
index 5941bde..91c95ad 100644 (file)
@@ -9,52 +9,58 @@ typedef struct {
     ObDirection dir;
 } Options;
 
-static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
-static void     free_func(gpointer options);
+static gpointer setup_north_func(ObParseInst *i, xmlDocPtr doc,
+                                 xmlNodePtr node);
+static gpointer setup_south_func(ObParseInst *i, xmlDocPtr doc,
+                                 xmlNodePtr node);
+static gpointer setup_east_func(ObParseInst *i, xmlDocPtr doc,
+                                xmlNodePtr node);
+static gpointer setup_west_func(ObParseInst *i, xmlDocPtr doc,
+                                xmlNodePtr node);
 static gboolean run_func(ObActionsData *data, gpointer options);
 
 void action_movetoedge_startup(void)
 {
-    actions_register("MoveToEdge",
-                     setup_func,
-                     free_func,
-                     run_func,
+    actions_register("MoveToEdgeNorth", setup_north_func, g_free, run_func,
+                     NULL, NULL);
+    actions_register("MoveToEdgeSouth", setup_south_func, g_free, run_func,
+                     NULL, NULL);
+    actions_register("MoveToEdgeEast", setup_east_func, g_free, run_func,
+                     NULL, NULL);
+    actions_register("MoveToEdgeWest", setup_west_func, g_free, run_func,
                      NULL, NULL);
 }
 
-static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
+static gpointer setup_north_func(ObParseInst *i, xmlDocPtr doc,
+                                 xmlNodePtr node)
 {
-    xmlNodePtr n;
-    Options *o;
-
-    o = g_new0(Options, 1);
+    Options *o = g_new0(Options, 1);
     o->dir = OB_DIRECTION_NORTH;
+    return o;
+}
 
-    if ((n = parse_find_node("direction", node))) {
-        gchar *s = parse_string(doc, n);
-        if (!g_ascii_strcasecmp(s, "north") ||
-            !g_ascii_strcasecmp(s, "up"))
-            o->dir = OB_DIRECTION_NORTH;
-        else if (!g_ascii_strcasecmp(s, "south") ||
-                 !g_ascii_strcasecmp(s, "down"))
-            o->dir = OB_DIRECTION_SOUTH;
-        else if (!g_ascii_strcasecmp(s, "west") ||
-                 !g_ascii_strcasecmp(s, "left"))
-            o->dir = OB_DIRECTION_WEST;
-        else if (!g_ascii_strcasecmp(s, "east") ||
-                 !g_ascii_strcasecmp(s, "right"))
-            o->dir = OB_DIRECTION_EAST;
-        g_free(s);
-    }
-
+static gpointer setup_south_func(ObParseInst *i, xmlDocPtr doc,
+                                 xmlNodePtr node)
+{
+    Options *o = g_new0(Options, 1);
+    o->dir = OB_DIRECTION_SOUTH;
     return o;
 }
 
-static void free_func(gpointer options)
+static gpointer setup_east_func(ObParseInst *i, xmlDocPtr doc,
+                                 xmlNodePtr node)
 {
-    Options *o = options;
+    Options *o = g_new0(Options, 1);
+    o->dir = OB_DIRECTION_EAST;
+    return o;
+}
 
-    g_free(o);
+static gpointer setup_west_func(ObParseInst *i, xmlDocPtr doc,
+                                 xmlNodePtr node)
+{
+    Options *o = g_new0(Options, 1);
+    o->dir = OB_DIRECTION_WEST;
+    return o;
 }
 
 /* Always return FALSE because its not interactive */
diff --git a/openbox/actions/shadelowerraise.c b/openbox/actions/shadelowerraise.c
new file mode 100644 (file)
index 0000000..e9ba12d
--- /dev/null
@@ -0,0 +1,39 @@
+#include "openbox/actions.h"
+#include "openbox/client.h"
+
+static gboolean run_func_sl(ObActionsData *data, gpointer options);
+static gboolean run_func_ur(ObActionsData *data, gpointer options);
+
+void action_shadelowerraise_startup()
+{
+    actions_register("ShadeLower", NULL, NULL, run_func_sl, NULL, NULL);
+    actions_register("UnshadeRaise", NULL, NULL, run_func_ur, NULL, NULL);
+}
+
+/* Always return FALSE because its not interactive */
+static gboolean run_func_sl(ObActionsData *data, gpointer options)
+{
+    if (data->client) {
+        actions_client_move(data, TRUE);
+        if (data->client->shaded)
+            stacking_lower(CLIENT_AS_WINDOW(data->client));
+        else
+            client_shade(data->client, TRUE);
+        actions_client_move(data, FALSE);
+    }
+    return FALSE;
+}
+
+/* Always return FALSE because its not interactive */
+static gboolean run_func_ur(ObActionsData *data, gpointer options)
+{
+    if (data->client) {
+        actions_client_move(data, TRUE);
+        if (data->client->shaded)
+            client_shade(data->client, FALSE);
+        else
+            stacking_raise(CLIENT_AS_WINDOW(data->client));
+        actions_client_move(data, FALSE);
+    }
+    return FALSE;
+}
index afea324..2d6885d 100644 (file)
@@ -372,7 +372,7 @@ void client_manage(Window window, ObPrompt *prompt)
         /* NET_WM_USER_TIME 0 when mapping means don't focus */
         (user_time != 0) &&
         /* this checks for focus=false for the window */
-        (!settings || settings->focus != 0) &&
+        settings->focus != 0 &&
         focus_valid_target(self, FALSE, FALSE, TRUE, FALSE, FALSE,
                            settings->focus == 1))
     {
@@ -782,7 +782,7 @@ static gboolean client_can_steal_focus(ObClient *self, Time steal_time,
 
     /* This is focus stealing prevention */
     ob_debug_type(OB_DEBUG_FOCUS,
-                  "Want to focus new window 0x%x at time %u "
+                  "Want to focus window 0x%x at time %u "
                   "launched at %u (last user interaction time %u)\n",
                   self->window, steal_time, launch_time,
                   event_last_user_time);
@@ -791,8 +791,9 @@ static gboolean client_can_steal_focus(ObClient *self, Time steal_time,
     if (!(self->desktop == screen_desktop ||
           self->desktop == DESKTOP_ALL) &&
         /* the timestamp is from before you changed desktops */
-        launch_time && screen_desktop_user_time &&
-        !event_time_after(launch_time, screen_desktop_user_time))
+        (!launch_time ||
+         (screen_desktop_user_time &&
+          !event_time_after(launch_time, screen_desktop_user_time))))
     {
         steal = FALSE;
         ob_debug_type(OB_DEBUG_FOCUS,
@@ -2238,7 +2239,7 @@ void client_update_icons(ObClient *self)
     */
     if (!self->icon_set && !self->parents) {
         RrPixel32 *icon = ob_rr_theme->def_win_icon;
-        gulong *ldata; /* use a long here to satisfy OBT_PROP_SETA32 */
+        gulong *ldata; /* use a long here to satisfy PROP_SETA32 */
 
         w = ob_rr_theme->def_win_icon_w;
         h = ob_rr_theme->def_win_icon_h;
@@ -2488,7 +2489,7 @@ ObClient *client_search_focus_tree_full(ObClient *self)
 
         for (it = self->parents; it; it = g_slist_next(it)) {
             ObClient *c = it->data;
-            if ((c = client_search_focus_tree_full(it->data))) return c;
+            if ((c = client_search_focus_tree_full(c))) return c;
         }
 
         return NULL;
@@ -3175,7 +3176,8 @@ void client_configure(ObClient *self, gint x, gint y, gint w, gint h,
 
     /* if it moved between monitors, then this can affect the stacking
        layer of this window or others - for fullscreen windows */
-    if (screen_find_monitor(&self->frame->area) !=
+    if (self->managed &&
+        screen_find_monitor(&self->frame->area) !=
         screen_find_monitor(&oldframe))
     {
         client_calc_layer(self);
@@ -3194,6 +3196,9 @@ void client_fullscreen(ObClient *self, gboolean fs)
 
     if (fs) {
         self->pre_fullscreen_area = self->area;
+        self->pre_fullscreen_max_horz = self->max_horz;
+        self->pre_fullscreen_max_vert = self->max_vert;
+
         /* if the window is maximized, its area isn't all that meaningful.
            save its premax area instead. */
         if (self->max_horz) {
@@ -3215,6 +3220,17 @@ void client_fullscreen(ObClient *self, gboolean fs)
         g_assert(self->pre_fullscreen_area.width > 0 &&
                  self->pre_fullscreen_area.height > 0);
 
+        self->max_horz = self->pre_fullscreen_max_horz;
+        self->max_vert = self->pre_fullscreen_max_vert;
+        if (self->max_horz) {
+            self->pre_max_area.x = self->pre_fullscreen_area.x;
+            self->pre_max_area.width = self->pre_fullscreen_area.width;
+        }
+        if (self->max_vert) {
+            self->pre_max_area.y = self->pre_fullscreen_area.y;
+            self->pre_max_area.height = self->pre_fullscreen_area.height;
+        }
+
         x = self->pre_fullscreen_area.x;
         y = self->pre_fullscreen_area.y;
         w = self->pre_fullscreen_area.width;
index e5a61d5..4ddfe66 100644 (file)
@@ -147,6 +147,9 @@ struct _ObClient
     Rect pre_max_area;
     /*! Position and size of the window prior to being fullscreened */
     Rect pre_fullscreen_area;
+    /*! Remember if the window was maximized before going fullscreen */
+    gboolean pre_fullscreen_max_horz,
+             pre_fullscreen_max_vert;
 
     /*! The window's strut
       The strut defines areas of the screen that are marked off-bounds for
@@ -325,14 +328,14 @@ void client_add_destroy_notify(ObClientCallback func, gpointer data);
 void client_remove_destroy_notify(ObClientCallback func);
 
 /*! Manages all existing windows */
-void client_manage_all();
+void client_manage_all(void);
 /*! Manages a given window
   @param prompt This specifies an ObPrompt which is being managed.  It is
                 possible to manage Openbox-owned windows through this.
 */
 void client_manage(Window win, struct _ObPrompt *prompt);
 /*! Unmanages all managed windows */
-void client_unmanage_all();
+void client_unmanage_all(void);
 /*! Unmanages a given client */
 void client_unmanage(ObClient *client);
 
@@ -345,7 +348,7 @@ ObClient *client_fake_manage(Window win);
 void client_fake_unmanage(ObClient *self);
 
 /*! Sets the client list on the root window from the client_list */
-void client_set_list();
+void client_set_list(void);
 
 /*! Determines if the client should be shown or hidden currently.
   @return TRUE if it should be visible; otherwise, FALSE.
@@ -731,7 +734,7 @@ void client_set_layer(ObClient *self, gint layer);
 
 guint client_monitor(ObClient *self);
 
-ObClient* client_under_pointer();
+ObClient* client_under_pointer(void);
 
 gboolean client_has_group_siblings(ObClient *self);
 
index 6c3147a..3876521 100644 (file)
@@ -118,7 +118,8 @@ static void client_menu_execute(ObMenuEntry *e, ObMenuFrame *f,
     gint x, y;
     gulong ignore_start;
 
-    g_assert(c);
+    if (!c)
+        return;
 
     if (!config_focus_under_mouse)
         ignore_start = event_start_ignore_all_enters();
index fe14502..5c55516 100644 (file)
@@ -19,6 +19,6 @@
 #ifndef ob__client_menu_h
 #define ob__client_menu_h
 
-void client_menu_startup();
+void client_menu_startup(void);
 
 #endif
index 240606a..503f028 100644 (file)
@@ -205,7 +205,7 @@ static void parse_per_app_settings(ObParseInst *inst, xmlDocPtr doc,
     gboolean x_pos_given;
 
     while (app) {
-        name_set = class_set = type_set = x_pos_given = FALSE;
+        x_pos_given = FALSE;
 
         class_set = parse_attr_string("class", app, &class);
         name_set = parse_attr_string("name", app, &name);
@@ -906,7 +906,7 @@ static void bind_default_mouse(void)
         { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "Raise" },
         { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "Raise" },
         { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Close" },
-        { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "ToggleMaximize" },
+        { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "ToggleMaximizeFull" },
         { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Iconify" },
         { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "ToggleOmnipresent" },
         { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "ToggleShade" },
@@ -1018,7 +1018,7 @@ void config_startup(ObParseInst *i)
 
     config_menu_hide_delay = 250;
     config_menu_middle = FALSE;
-    config_submenu_show_delay = 200;
+    config_submenu_show_delay = 100;
     config_submenu_hide_delay = 400;
     config_menu_client_list_icons = TRUE;
     config_menu_manage_desktops = TRUE;
index 7713936..c82ffbf 100644 (file)
@@ -197,10 +197,10 @@ extern GSList *config_menu_files;
 extern GSList *config_per_app_settings;
 
 void config_startup(struct _ObParseInst *i);
-void config_shutdown();
+void config_shutdown(void);
 
 /*! Create an ObAppSettings structure with the default values */
-ObAppSettings* config_create_app_settings();
+ObAppSettings* config_create_app_settings(void);
 /*! Copies any settings in src to dest, if they are their default value in
   src. */
 void config_app_settings_copy_non_defaults(const ObAppSettings *src,
index 57c1f39..dab71f5 100644 (file)
@@ -68,12 +68,12 @@ extern StrutPartial dock_strut;
 void dock_startup(gboolean reconfig);
 void dock_shutdown(gboolean reconfig);
 
-void dock_configure();
+void dock_configure(void);
 void dock_hide(gboolean hide);
 
 void dock_add(Window win, XWMHints *wmhints);
 
-void dock_remove_all();
+void dock_remove_all(void);
 void dock_remove(ObDockApp *app, gboolean reparent);
 
 void dock_app_drag(ObDockApp *app, XMotionEvent *e);
index 2ebea6b..1c6c043 100644 (file)
@@ -652,6 +652,7 @@ static void event_process(const XEvent *ec, gpointer data)
         /* keyboard layout changes for modifier mapping changes. reload the
            modifier map, and rebind all the key bindings as appropriate */
         ob_debug("Keyboard map changed. Reloading keyboard bindings.\n");
+        XRefreshKeyboardMapping(&e->xmapping);
         ob_set_state(OB_STATE_RECONFIGURING);
         modkeys_shutdown(TRUE);
         modkeys_startup(TRUE);
@@ -1323,11 +1324,23 @@ static void event_handle_client(ObClient *client, XEvent *e)
                        (e->xclient.data.l[0] == 2 ? "user" : "INVALID"))));
             /* XXX make use of data.l[2] !? */
             if (e->xclient.data.l[0] == 1 || e->xclient.data.l[0] == 2) {
-                event_curtime = e->xclient.data.l[1];
+                /* we can not trust the timestamp from applications.
+                   e.g. chromium passes a very old timestamp.  openbox thinks
+                   the window will get focus and calls XSetInputFocus with the
+                   (old) timestamp, which doesn't end up moving focus at all.
+                   but the window is raised, not hilited, etc, as if it was
+                   really going to get focus.
+
+                   so do not use this timestamp in event_curtime, as this would
+                   be used in XSetInputFocus.
+                */
+                /*event_curtime = e->xclient.data.l[1];*/
                 if (e->xclient.data.l[1] == 0)
                     ob_debug_type(OB_DEBUG_APP_BUGS,
                                   "_NET_ACTIVE_WINDOW message for window %s is"
                                   " missing a timestamp\n", client->title);
+
+                event_curtime = event_get_server_time();
             } else
                 ob_debug_type(OB_DEBUG_APP_BUGS,
                               "_NET_ACTIVE_WINDOW message for window %s is "
@@ -1712,7 +1725,9 @@ static gboolean event_handle_menu_keyboard(XEvent *ev)
 
         else if (ob_keycode_match(keycode, OB_KEY_RIGHT)) {
             /* Right goes to the selected submenu */
-            if (frame->selected->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) {
+            if (frame->selected &&
+                frame->selected->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU)
+            {
                 /* make sure it is visible */
                 menu_frame_select(frame, frame->selected, TRUE);
                 menu_frame_select_next(frame->child);
index a4bd886..231ccb4 100644 (file)
@@ -47,7 +47,7 @@ void event_enter_client(struct _ObClient *client);
 
 /*! Make mouse focus not move at all from the stuff that happens between these
     two function calls. */
-gulong event_start_ignore_all_enters();
+gulong event_start_ignore_all_enters(void);
 void event_end_ignore_all_enters(gulong start);
 
 /*! End *all* active and passive grabs on the keyboard
@@ -57,16 +57,16 @@ void event_end_ignore_all_enters(gulong start);
 
     Actions should not rely on being able to move focus during an
     interactive grab. */
-void event_cancel_all_key_grabs();
+void event_cancel_all_key_grabs(void);
 
 /* Halts any focus delay in progress, use this when the user is selecting a
    window for focus */
-void event_halt_focus_delay();
+void event_halt_focus_delay(void);
 
 /*! Compare t1 and t2, taking into account wraparound. True if t1
     comes at the same time or later than t2. */
 gboolean event_time_after(guint32 t1, guint32 t2);
 
-Time event_get_server_time();
+Time event_get_server_time(void);
 
 #endif
index 3155874..9f74b10 100644 (file)
@@ -67,7 +67,7 @@ extern gboolean extensions_sync;
 /*! Base for events for the Sync extension */
 extern gint extensions_sync_event_basep;
 
-void extensions_query_all();
+void extensions_query_all(void);
 
 void extensions_xinerama_screens(Rect **areas, guint *nxin);
 
index 36d754f..07e74af 100644 (file)
@@ -345,13 +345,17 @@ gboolean focus_valid_target(ObClient *ft,
                   that can be focused instead */
                !focus_target_has_siblings(ft, iconic_windows, all_desktops))));
 
-    /* it's not set to skip the taskbar (but this only applies to normal typed
-       windows, and is overridden if the window is modal or if the user asked
-       for this window to be focused) */
-    ok = ok && (ft->type != OB_CLIENT_TYPE_NORMAL ||
-                ft->modal ||
-                user_request ||
-                !ft->skip_taskbar);
+    /* it's not set to skip the taskbar (but this is overridden if the
+       window is modal or if the user asked for this window to be focused,
+       or if the window is iconified (and does not have any parents with
+       which to uniconify it), and it is not used for windows which are
+       hilited, or dialog windows as these need user interaction and should
+       not be long-lasting windows */
+    ok = ok && (!ft->skip_taskbar ||
+                (ft->modal || user_request ||
+                 (ft->iconic && !ft->parents) ||
+                 ft->demands_attention ||
+                 ft->type == OB_CLIENT_TYPE_DIALOG));
 
     /* it's not going to just send focus off somewhere else (modal window),
        unless that modal window is not one of our valid targets, then let
index c8af110..09b769c 100644 (file)
@@ -41,7 +41,7 @@ void focus_shutdown(gboolean reconfig);
 void focus_set_client(struct _ObClient *client);
 
 /*! Focus nothing, but let keyboard events be caught. */
-void focus_nothing();
+void focus_nothing(void);
 
 /*! Call this when you need to focus something! */
 struct _ObClient* focus_fallback(gboolean allow_refocus,
index d7ac9f5..c48b8f2 100644 (file)
@@ -317,7 +317,7 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c)
     gint innerw, innerh;
     gint i;
     GList *it;
-    const ObFocusCyclePopupTarget *newtarget;
+    const ObFocusCyclePopupTarget *newtarget = NULL;
     gint newtargetx, newtargety;
 
     screen_area = screen_physical_area_primary(FALSE);
index 934d9a6..88c2f53 100644 (file)
@@ -30,14 +30,14 @@ void focus_cycle_popup_shutdown(gboolean reconfig);
 void focus_cycle_popup_show(struct _ObClient *c, gboolean iconic_windows,
                             gboolean all_desktops, gboolean dock_windows,
                             gboolean desktop_windows);
-void focus_cycle_popup_hide();
+void focus_cycle_popup_hide(void);
 
 void focus_cycle_popup_single_show(struct _ObClient *c,
                                    gboolean iconic_windows,
                                    gboolean all_desktops,
                                    gboolean dock_windows,
                                    gboolean desktop_windows);
-void focus_cycle_popup_single_hide();
+void focus_cycle_popup_single_hide(void);
 
 gboolean focus_cycle_popup_is_showing(struct _ObClient *c);
 
index 67adb40..64dd290 100644 (file)
@@ -1317,6 +1317,8 @@ ObFrameContext frame_context_from_string(const gchar *name)
         return OB_FRAME_CONTEXT_TOP;
     else if (!g_ascii_strcasecmp("Bottom", name))
         return OB_FRAME_CONTEXT_BOTTOM;
+    else if (!g_ascii_strcasecmp("Handle", name))
+        return OB_FRAME_CONTEXT_BOTTOM;
     else if (!g_ascii_strcasecmp("Left", name))
         return OB_FRAME_CONTEXT_LEFT;
     else if (!g_ascii_strcasecmp("Right", name))
index 30c4b70..8253637 100644 (file)
@@ -38,8 +38,8 @@ gint grab_server(gboolean grab);
 #define grab_pointer(o,c,u) grab_pointer_full(TRUE, (o), (c), (u))
 #define ungrab_pointer() grab_pointer_full(FALSE, FALSE, FALSE, OB_CURSOR_NONE)
 
-gboolean grab_on_keyboard();
-gboolean grab_on_pointer();
+gboolean grab_on_keyboard(void);
+gboolean grab_on_pointer(void);
 
 void grab_button_full(guint button, guint state, Window win, guint mask,
                       gint pointer_mode, ObCursor cursor);
@@ -50,6 +50,6 @@ void grab_key(guint keycode, guint state, Window win, gint keyboard_mode);
 void ungrab_all_keys(Window win);
 
 void grab_key_passive_count(int change);
-void ungrab_passive_key();
+void ungrab_passive_key(void);
 
 #endif
index 995cdbc..1674cf9 100644 (file)
@@ -34,11 +34,11 @@ extern KeyBindingTree *keyboard_firstnode;
 void keyboard_startup(gboolean reconfig);
 void keyboard_shutdown(gboolean reconfig);
 
-void keyboard_rebind();
+void keyboard_rebind(void);
 
 void keyboard_chroot(GList *keylist);
 gboolean keyboard_bind(GList *keylist, struct _ObActionsAct *action);
-void keyboard_unbind_all();
+void keyboard_unbind_all(void);
 
 void keyboard_event(struct _ObClient *client, const XEvent *e);
 /*! @param break_chroots how many chroots to break. -1 means to break them ALL!
index 58b6280..22c1046 100644 (file)
@@ -62,13 +62,6 @@ static gunichar parse_shortcut(const gchar *label, gboolean allow_shortcut,
                                gchar **strippedlabel, guint *position,
                                gboolean *always_show);
 
-static void client_dest(ObClient *client, gpointer data)
-{
-    /* menus can be associated with a client, so close any that are since
-       we are disappearing now */
-    menu_frame_hide_all_client(client);
-}
-
 void menu_startup(gboolean reconfig)
 {
     xmlDocPtr doc;
@@ -112,16 +105,10 @@ void menu_startup(gboolean reconfig)
     }
 
     g_assert(menu_parse_state.parent == NULL);
-
-    if (!reconfig)
-        client_add_destroy_notify(client_dest, NULL);
 }
 
 void menu_shutdown(gboolean reconfig)
 {
-    if (!reconfig)
-        client_remove_destroy_notify(client_dest);
-
     parse_shutdown(menu_parse_inst);
     menu_parse_inst = NULL;
 
@@ -218,6 +205,7 @@ static gunichar parse_shortcut(const gchar *label, gboolean allow_shortcut,
         *strippedlabel = NULL;
     } else {
         gchar *i;
+        gboolean escape;
 
         *strippedlabel = g_strdup(label);
 
@@ -225,20 +213,33 @@ static gunichar parse_shortcut(const gchar *label, gboolean allow_shortcut,
            have to just use the first valid character
         */
 
-        i = strchr(*strippedlabel, '_');
+        /* allow __ to escape an underscore */
+        i = *strippedlabel;
+        do {
+            escape = FALSE;
+            i = strchr(i, '_');
+            if (i && *(i+1) == '_') {
+                gchar *j;
+
+                /* remove the escape '_' from the string */
+                for (j = i; *j != '\0'; ++j)
+                    *j = *(j+1);
+
+                ++i;
+                escape = TRUE;
+            }
+        } while (escape);
+
         if (allow_shortcut && i != NULL) {
             /* there is an underscore in the string */
 
             /* you have to use a printable ascii character for shortcuts
                don't allow space either, so you can have like "a _ b"
             */
-            if (VALID_SHORTCUT(*(i+1)) || *(i+1) == '_') {
-                /* Allow you to escape the first _ by putting __ */
-                if (*(i+1) != '_') {
-                    shortcut = g_unichar_tolower(g_utf8_get_char(i+1));
-                    *position = i - *strippedlabel;
-                    *always_show = TRUE;
-                }
+            if (VALID_SHORTCUT(*(i+1))) {
+                shortcut = g_unichar_tolower(g_utf8_get_char(i+1));
+                *position = i - *strippedlabel;
+                *always_show = TRUE;
 
                 /* remove the '_' from the string */
                 for (; *i != '\0'; ++i)
index 7e11545..a472226 100644 (file)
@@ -169,13 +169,13 @@ void menu_free(ObMenu *menu);
 /*! Repopulate a pipe-menu by running its command */
 void menu_pipe_execute(ObMenu *self);
 /*! Clear a pipe-menu's entries */
-void menu_clear_pipe_caches();
+void menu_clear_pipe_caches(void);
 
 void menu_show_all_shortcuts(ObMenu *self, gboolean show);
 
 void menu_show(gchar *name, gint x, gint y, gboolean mouse,
                struct _ObClient *client);
-gboolean menu_hide_delay_reached();
+gboolean menu_hide_delay_reached(void);
 
 void menu_set_show_func(ObMenu *menu, ObMenuShowFunc func);
 void menu_set_hide_func(ObMenu *menu, ObMenuHideFunc func);
index f013bde..fa65c85 100644 (file)
@@ -62,6 +62,19 @@ static Window createWindow(Window parent, gulong mask,
                          RrVisual(ob_rr_inst), mask, attrib);
 }
 
+static void client_dest(ObClient *client, gpointer data)
+{
+    GList *it;
+
+    /* menus can be associated with a client, so null those refs since
+       we are disappearing now */
+    for (it = menu_frame_visible; it; it = g_list_next(it)) {
+        ObMenuFrame *f = it->data;
+        if (f->client == client)
+            f->client = NULL;
+    }
+}
+
 void menu_frame_startup(gboolean reconfig)
 {
     gint i;
@@ -76,6 +89,7 @@ void menu_frame_startup(gboolean reconfig)
 
     if (reconfig) return;
 
+    client_add_destroy_notify(client_dest, NULL);
     menu_frame_map = g_hash_table_new(g_int_hash, g_int_equal);
 }
 
@@ -85,6 +99,7 @@ void menu_frame_shutdown(gboolean reconfig)
 
     if (reconfig) return;
 
+    client_remove_destroy_notify(client_dest);
     g_hash_table_destroy(menu_frame_map);
 }
 
@@ -639,7 +654,6 @@ void menu_frame_render(ObMenuFrame *self)
     if (self->entries) {
         gint l, t, r, b;
 
-        e = self->entries->data;
         ob_rr_theme->a_menu_text_normal->texture[0].data.text.string = "";
         tw = RrMinWidth(ob_rr_theme->a_menu_text_normal);
         tw += 2*PADDING;
@@ -1079,22 +1093,6 @@ void menu_frame_hide_all(void)
         menu_frame_hide(it->data);
 }
 
-void menu_frame_hide_all_client(ObClient *client)
-{
-    GList *it = g_list_last(menu_frame_visible);
-    if (it) {
-        ObMenuFrame *f = it->data;
-        if (f->client == client) {
-            if (config_submenu_show_delay) {
-                /* remove any submenu open requests */
-                ob_main_loop_timeout_remove(ob_main_loop,
-                                            submenu_show_timeout);
-            }
-            menu_frame_hide(f);
-        }
-    }
-}
-
 ObMenuFrame* menu_frame_under(gint x, gint y)
 {
     ObMenuFrame *ret = NULL;
@@ -1255,7 +1253,7 @@ void menu_entry_frame_execute(ObMenuEntryFrame *self, guint state)
 
         /* release grabs before executing the shit */
         if (!(state & ControlMask)) {
-            menu_frame_hide_all();
+            event_cancel_all_key_grabs();
             frame = NULL;
         }
 
index da796d5..3a42c44 100644 (file)
@@ -118,7 +118,7 @@ gboolean menu_frame_show_topmenu(ObMenuFrame *self, gint x, gint y,
 gboolean menu_frame_show_submenu(ObMenuFrame *self, ObMenuFrame *parent,
                                  ObMenuEntryFrame *parent_entry);
 
-void menu_frame_hide_all();
+void menu_frame_hide_all(void);
 void menu_frame_hide_all_client(struct _ObClient *client);
 
 void menu_frame_render(ObMenuFrame *self);
index e897ccb..a54fdf0 100644 (file)
@@ -189,7 +189,7 @@ KeyCode* modkeys_sym_to_code(KeySym sym)
     for (i = min_keycode; i <= max_keycode; ++i)
         for (j = 0; j < keysyms_per_keycode; ++j)
             if (sym == keymap[(i-min_keycode) * keysyms_per_keycode + j]) {
-                ret = g_renew(KeyCode, ret, ++n);
+                ret = g_renew(KeyCode, ret, ++n + 1);
                 ret[n-1] = i;
                 ret[n] = 0;
             }
index f63d266..9ce84e2 100644 (file)
@@ -197,7 +197,7 @@ static gboolean fire_binding(ObMouseAction a, ObFrameContext context,
     return TRUE;
 }
 
-void mouse_replay_pointer()
+void mouse_replay_pointer(void)
 {
     if (replay_pointer_needed) {
         /* replay the pointer event before any windows move */
index a862fe5..2bd5d57 100644 (file)
@@ -31,7 +31,7 @@ void mouse_shutdown(gboolean reconfig);
 
 gboolean mouse_bind(const gchar *buttonstr, const gchar *contextstr,
                     ObMouseAction mact, struct _ObActionsAct *action);
-void mouse_unbind_all();
+void mouse_unbind_all(void);
 
 void mouse_event(struct _ObClient *client, XEvent *e);
 
@@ -43,6 +43,6 @@ ObFrameContext mouse_button_frame_context(ObFrameContext context,
 /*! If a replay pointer is needed, then do it.  Call this when windows are
   going to be moving/appearing/disappearing, so that you know the mouse click
   will go to the right window */
-void mouse_replay_pointer();
+void mouse_replay_pointer(void);
 
 #endif
index 95d6473..39ae5b7 100644 (file)
@@ -300,11 +300,7 @@ void moveresize_end(gboolean cancel)
 
     popup_hide(popup);
 
-    if (moving) {
-        client_move(moveresize_client,
-                    (cancel ? start_cx : cur_x),
-                    (cancel ? start_cy : cur_y));
-    } else {
+    if (!moving) {
 #ifdef SYNC
         /* turn off the alarm */
         if (moveresize_alarm != None) {
@@ -314,15 +310,19 @@ void moveresize_end(gboolean cancel)
 
         ob_main_loop_timeout_remove(ob_main_loop, sync_timeout_func);
 #endif
-
-        client_configure(moveresize_client,
-                         (cancel ? start_cx : cur_x),
-                         (cancel ? start_cy : cur_y),
-                         (cancel ? start_cw : cur_w),
-                         (cancel ? start_ch : cur_h),
-                         TRUE, TRUE, FALSE);
     }
 
+    /* don't use client_move() here, use the same width/height as
+       we've been using during the move, otherwise we get different results
+       when moving maximized windows between monitors of different sizes !
+    */
+    client_configure(moveresize_client,
+                     (cancel ? start_cx : cur_x),
+                     (cancel ? start_cy : cur_y),
+                     (cancel ? start_cw : cur_w),
+                     (cancel ? start_ch : cur_h),
+                     TRUE, TRUE, FALSE);
+
     /* dont edge warp after its ended */
     cancel_edge_warp();
 
@@ -655,7 +655,7 @@ static void move_with_keys(gint keycode, gint state)
 static void resize_with_keys(gint keycode, gint state)
 {
     gint dw = 0, dh = 0, pdx = 0, pdy = 0, opx, opy, px, py;
-    gint dist = 0, resist = 0;
+    gint resist = 0;
     ObDirection dir;
 
     /* pick the edge if it needs to move */
@@ -745,27 +745,27 @@ static void resize_with_keys(gint keycode, gint state)
 
         if (key_resize_edge == OB_DIRECTION_WEST) {
             if (dir == OB_DIRECTION_WEST)
-                dw = (dist = distw);
+                dw = distw;
             else
-                dw = -(dist = distw);
+                dw = -distw;
         }
         else if (key_resize_edge == OB_DIRECTION_EAST) {
             if (dir == OB_DIRECTION_EAST)
-                dw = (dist = distw);
+                dw = distw;
             else
-                dw = -(dist = distw);
+                dw = -distw;
         }
         else if (key_resize_edge == OB_DIRECTION_NORTH) {
             if (dir == OB_DIRECTION_NORTH)
-                dh = (dist = disth);
+                dh = disth;
             else
-                dh = -(dist = disth);
+                dh = -disth;
         }
         else /*if (key_resize_edge == OB_DIRECTION_SOUTH)*/ {
             if (dir == OB_DIRECTION_SOUTH)
-                dh = (dist = disth);
+                dh = disth;
             else
-                dh = -(dist = disth);
+                dh = -disth;
         }
     }
 
index 415c160..12fb2f6 100644 (file)
@@ -175,6 +175,8 @@ gint main(gint argc, gchar **argv)
     ob_main_loop_signal_add(ob_main_loop, SIGHUP, signal_handler, NULL, NULL);
     ob_main_loop_signal_add(ob_main_loop, SIGPIPE, signal_handler, NULL, NULL);
     ob_main_loop_signal_add(ob_main_loop, SIGCHLD, signal_handler, NULL, NULL);
+    ob_main_loop_signal_add(ob_main_loop, SIGTTIN, signal_handler, NULL,NULL);
+    ob_main_loop_signal_add(ob_main_loop, SIGTTOU, signal_handler, NULL,NULL);
 
     ob_screen = DefaultScreen(ob_display);
 
@@ -520,6 +522,10 @@ static void signal_handler(gint signal, gpointer data)
         /* reap children */
         while (waitpid(-1, NULL, WNOHANG) > 0);
         break;
+    case SIGTTIN:
+    case SIGTTOU:
+        ob_debug("Caught signal %d. Ignoring.", signal);
+        break;
     default:
         ob_debug("Caught signal %d. Exiting.\n", signal);
         /* TERM and INT return a 0 code */
@@ -527,7 +533,7 @@ static void signal_handler(gint signal, gpointer data)
     }
 }
 
-static void print_version()
+static void print_version(void)
 {
     g_print("Openbox %s\n", PACKAGE_VERSION);
     g_print(_("Copyright (c)"));
@@ -539,7 +545,7 @@ static void print_version()
     g_print("under certain conditions. See the file COPYING for details.\n\n");
 }
 
-static void print_help()
+static void print_help(void)
 {
     g_print(_("Syntax: openbox [options]\n"));
     g_print(_("\nOptions:\n"));
@@ -574,7 +580,7 @@ static void remove_args(gint *argc, gchar **argv, gint index, gint num)
     *argc -= num;
 }
 
-static void parse_env()
+static void parse_env(void)
 {
     const gchar *id;
 
@@ -705,7 +711,7 @@ static Cursor load_cursor(const gchar *name, guint fontval)
 
 void ob_exit_with_error(const gchar *msg)
 {
-    g_message(msg);
+    g_message("%s", msg);
     session_shutdown(TRUE);
     exit(EXIT_FAILURE);
 }
@@ -716,13 +722,13 @@ void ob_restart_other(const gchar *path)
     ob_restart();
 }
 
-void ob_restart()
+void ob_restart(void)
 {
     restart = TRUE;
     ob_exit(0);
 }
 
-void ob_reconfigure()
+void ob_reconfigure(void)
 {
     reconfigure = TRUE;
     ob_exit(0);
@@ -734,7 +740,7 @@ void ob_exit(gint code)
     ob_main_loop_exit(ob_main_loop);
 }
 
-void ob_exit_replace()
+void ob_exit_replace(void)
 {
     exitcode = 0;
     being_replaced = TRUE;
@@ -757,7 +763,7 @@ gboolean ob_keycode_match(KeyCode code, ObKey key)
     return FALSE;
 }
 
-ObState ob_state()
+ObState ob_state(void)
 {
     return state;
 }
index 76b04ea..b72916b 100644 (file)
@@ -51,15 +51,15 @@ extern gboolean ob_replace_wm;
 extern gboolean ob_debug_xinerama;
 
 /* The state of execution of the window manager */
-ObState ob_state();
+ObState ob_state(void);
 void ob_set_state(ObState state);
 
 void ob_restart_other(const gchar *path);
-void ob_restart();
+void ob_restart(void);
 void ob_exit(gint code);
-void ob_exit_replace();
+void ob_exit_replace(void);
 
-void ob_reconfigure();
+void ob_reconfigure(void);
 
 void ob_exit_with_error(const gchar *msg);
 
index 2b01ce2..503e277 100644 (file)
@@ -77,7 +77,7 @@ struct _ObPagerPopup
     RrAppearance *unhilight;
 };
 
-ObPopup *popup_new();
+ObPopup *popup_new(void);
 void popup_free(ObPopup *self);
 
 /*! Position the popup. The gravity rules are not the same X uses for windows,
@@ -105,7 +105,7 @@ void popup_hide(ObPopup *self);
 RrAppearance *popup_icon_appearance(ObPopup *self);
 
 
-ObIconPopup *icon_popup_new();
+ObIconPopup *icon_popup_new(void);
 void icon_popup_free(ObIconPopup *self);
 
 #define icon_popup_show(s, t, i) icon_popup_delay_show((s),0,(t),(i))
@@ -124,7 +124,7 @@ void icon_popup_delay_show(ObIconPopup *self, gulong usec,
 #define icon_popup_set_text_align(p, j) popup_set_text_align((p)->popup,(j))
 void icon_popup_icon_size_multiplier(ObIconPopup *self, guint wm, guint hm);
 
-ObPagerPopup *pager_popup_new();
+ObPagerPopup *pager_popup_new(void);
 void pager_popup_free(ObPagerPopup *self);
 
 #define pager_popup_show(s, t, d) pager_popup_delay_show((s),0,(t),(d))
index bef06a7..a97cd1b 100644 (file)
@@ -95,17 +95,17 @@ void prompt_startup(gboolean reconfig)
     prompt_a_button->texture[0].data.text.color = c_button;
     prompt_a_focus->texture[0].data.text.color = c_focus;
     prompt_a_press->texture[0].data.text.color = c_press;
-    prompt_a_pfocus->texture[0].data.text.color = c_press;
+    prompt_a_pfocus->texture[0].data.text.color = c_pfocus;
 
     prompt_a_focus->texture[1].data.lineart.color = c_focus;
     prompt_a_focus->texture[2].data.lineart.color = c_focus;
     prompt_a_focus->texture[3].data.lineart.color = c_focus;
     prompt_a_focus->texture[4].data.lineart.color = c_focus;
 
-    prompt_a_pfocus->texture[1].data.lineart.color = c_press;
-    prompt_a_pfocus->texture[2].data.lineart.color = c_press;
-    prompt_a_pfocus->texture[3].data.lineart.color = c_press;
-    prompt_a_pfocus->texture[4].data.lineart.color = c_press;
+    prompt_a_pfocus->texture[1].data.lineart.color = c_pfocus;
+    prompt_a_pfocus->texture[2].data.lineart.color = c_pfocus;
+    prompt_a_pfocus->texture[3].data.lineart.color = c_pfocus;
+    prompt_a_pfocus->texture[4].data.lineart.color = c_pfocus;
 
     prompt_a_msg = RrAppearanceCopy(ob_rr_theme->osd_hilite_label);
     prompt_a_msg->texture[0].data.text.flow = TRUE;
index 7164567..4fcded2 100644 (file)
@@ -210,7 +210,7 @@ typedef struct Atoms {
 } Atoms;
 extern Atoms prop_atoms;
 
-void prop_startup();
+void prop_startup(void);
 
 gboolean prop_get32(Window win, Atom prop, Atom type, guint32 *ret);
 gboolean prop_get_array32(Window win, Atom prop, Atom type, guint32 **ret,
index 91eabcb..9b785a3 100644 (file)
@@ -330,7 +330,6 @@ void resist_size_monitors(ObClient *c, gint resist, gint *w, gint *h,
     Rect *area, *parea;
     gint al, at, ar, ab; /* screen boundaries */
     gint pl, pt, pr, pb; /* physical screen boundaries */
-    gint incw, inch;
     guint i;
     Rect desired_area;
 
@@ -341,9 +340,6 @@ void resist_size_monitors(ObClient *c, gint resist, gint *w, gint *h,
     t = RECT_TOP(c->frame->area);
     b = RECT_BOTTOM(c->frame->area);
 
-    incw = c->size_inc.width;
-    inch = c->size_inc.height;
-
     RECT_SET(desired_area, c->area.x, c->area.y, *w, *h);
 
     for (i = 0; i < screen_num_monitors; ++i) {
index 55fd58d..d11c0b6 100644 (file)
@@ -513,7 +513,6 @@ void screen_resize(void)
 
 void screen_set_num_desktops(guint num)
 {
-    guint old;
     gulong *viewport;
     GList *it, *stacking_copy;
 
@@ -521,7 +520,6 @@ void screen_set_num_desktops(guint num)
 
     if (screen_num_desktops == num) return;
 
-    old = screen_num_desktops;
     screen_num_desktops = num;
     PROP_SET32(RootWindow(ob_display, ob_screen),
                net_number_of_desktops, cardinal, num);
@@ -1462,7 +1460,7 @@ Rect* screen_area(guint desktop, guint head, Rect *search)
 {
     Rect *a;
     GSList *it;
-    gint l, r, t, b, al, ar, at, ab;
+    gint l, r, t, b;
     guint i, d;
     gboolean us = search != NULL; /* user provided search */
 
@@ -1482,36 +1480,32 @@ Rect* screen_area(guint desktop, guint head, Rect *search)
     }
     if (head == SCREEN_AREA_ONE_MONITOR) head = screen_find_monitor(search);
 
-    /* al is "all left" meaning the furthest left you can get, l is our
-       "working left" meaning our current strut edge which we're calculating
-    */
-
     /* only include monitors which the search area lines up with */
     if (RECT_INTERSECTS_RECT(monitor_area[screen_num_monitors], *search)) {
-        al = l = RECT_RIGHT(monitor_area[screen_num_monitors]);
-        at = t = RECT_BOTTOM(monitor_area[screen_num_monitors]);
-        ar = r = RECT_LEFT(monitor_area[screen_num_monitors]);
-        ab = b = RECT_TOP(monitor_area[screen_num_monitors]);
+        l = RECT_RIGHT(monitor_area[screen_num_monitors]);
+        t = RECT_BOTTOM(monitor_area[screen_num_monitors]);
+        r = RECT_LEFT(monitor_area[screen_num_monitors]);
+        b = RECT_TOP(monitor_area[screen_num_monitors]);
         for (i = 0; i < screen_num_monitors; ++i) {
             /* add the monitor if applicable */
             if (RANGES_INTERSECT(search->x, search->width,
                                  monitor_area[i].x, monitor_area[i].width))
             {
-                at = t = MIN(t, RECT_TOP(monitor_area[i]));
-                ab = b = MAX(b, RECT_BOTTOM(monitor_area[i]));
+                t = MIN(t, RECT_TOP(monitor_area[i]));
+                b = MAX(b, RECT_BOTTOM(monitor_area[i]));
             }
             if (RANGES_INTERSECT(search->y, search->height,
                                  monitor_area[i].y, monitor_area[i].height))
             {
-                al = l = MIN(l, RECT_LEFT(monitor_area[i]));
-                ar = r = MAX(r, RECT_RIGHT(monitor_area[i]));
+                l = MIN(l, RECT_LEFT(monitor_area[i]));
+                r = MAX(r, RECT_RIGHT(monitor_area[i]));
             }
         }
     } else {
-        al = l = RECT_LEFT(monitor_area[screen_num_monitors]);
-        at = t = RECT_TOP(monitor_area[screen_num_monitors]);
-        ar = r = RECT_RIGHT(monitor_area[screen_num_monitors]);
-        ab = b = RECT_BOTTOM(monitor_area[screen_num_monitors]);
+        l = RECT_LEFT(monitor_area[screen_num_monitors]);
+        t = RECT_TOP(monitor_area[screen_num_monitors]);
+        r = RECT_RIGHT(monitor_area[screen_num_monitors]);
+        b = RECT_BOTTOM(monitor_area[screen_num_monitors]);
     }
 
     for (d = 0; d < screen_num_desktops; ++d) {
index 1690330..750de94 100644 (file)
@@ -53,7 +53,7 @@ extern ObDesktopLayout screen_desktop_layout;
 extern gchar **screen_desktop_names;
 
 /*! Take over the screen, set the basic hints on it claming it as ours */
-gboolean screen_annex();
+gboolean screen_annex(void);
 
 /*! Once the screen is ours, set up its initial state */
 void screen_startup(gboolean reconfig);
@@ -61,7 +61,7 @@ void screen_startup(gboolean reconfig);
 void screen_shutdown(gboolean reconfig);
 
 /*! Figure out the new size of the screen and adjust stuff for it */
-void screen_resize();
+void screen_resize(void);
 
 /*! Change the number of available desktops */
 void screen_set_num_desktops(guint num);
@@ -78,7 +78,7 @@ guint screen_find_desktop(guint from, ObDirection dir,
 /*! Show the desktop popup/notification */
 void screen_show_desktop_popup(guint d);
 /*! Hide it */
-void screen_hide_desktop_popup();
+void screen_hide_desktop_popup(void);
 
 /*! Shows and focuses the desktop and hides all the client windows, or
   returns to the normal state, showing client windows.
@@ -89,18 +89,18 @@ void screen_hide_desktop_popup();
 void screen_show_desktop(gboolean show, struct _ObClient *show_only);
 
 /*! Updates the desktop layout from the root property if available */
-void screen_update_layout();
+void screen_update_layout(void);
 
 /*! Get desktop names from the root window property */
-void screen_update_desktop_names();
+void screen_update_desktop_names(void);
 
 /*! Installs or uninstalls a colormap for a client. If client is NULL, then
   it handles the root colormap. */
 void screen_install_colormap(struct _ObClient *client, gboolean install);
 
-void screen_update_areas();
+void screen_update_areas(void);
 
-Rect *screen_physical_area_all_monitors();
+Rect *screen_physical_area_all_monitors(void);
 
 Rect *screen_physical_area_monitor(guint head);
 
@@ -147,7 +147,7 @@ guint screen_find_monitor_point(guint x, guint y);
 
 /*! Sets the root cursor. This function decides which cursor to use, but you
   gotta call it to let it know it should change. */
-void screen_set_root_cursor();
+void screen_set_root_cursor(void);
 
 /*! Gives back the pointer's position in x and y. Returns TRUE if the pointer
   is on this screen and FALSE if it is on another screen. */
index 1401847..4e6dd81 100644 (file)
@@ -162,7 +162,7 @@ gboolean session_connected(void)
 }
 
 /*! Connect to the session manager and set up our callback functions */
-static gboolean session_connect()
+static gboolean session_connect(void)
 {
     SmcCallbacks cb;
     gchar *oldid;
@@ -196,7 +196,7 @@ static gboolean session_connect()
     return sm_conn != NULL;
 }
 
-static void session_setup_program()
+static void session_setup_program(void)
 {
     SmPropValue vals = {
         .value = sm_argv[0],
@@ -215,7 +215,7 @@ static void session_setup_program()
     g_free(prop.type);
 }
 
-static void session_setup_user()
+static void session_setup_user(void)
 {
     char *user = g_strdup(g_get_user_name());
 
@@ -258,7 +258,7 @@ static void session_setup_restart_style(gboolean restart)
     g_free(prop.type);
 }
 
-static void session_setup_pid()
+static void session_setup_pid(void)
 {
     gchar *pid = g_strdup_printf("%ld", (glong) getpid());
 
@@ -281,7 +281,7 @@ static void session_setup_pid()
 }
 
 /*! This is a gnome-session-manager extension */
-static void session_setup_priority()
+static void session_setup_priority(void)
 {
     gchar priority = 20; /* 20 is a lower prioity to run before other apps */
 
@@ -302,7 +302,7 @@ static void session_setup_priority()
     g_free(prop.type);
 }
 
-static void session_setup_clone_command()
+static void session_setup_clone_command(void)
 {
     gint i;
 
@@ -328,7 +328,7 @@ static void session_setup_clone_command()
     g_free(vals);
 }
 
-static void session_setup_restart_command()
+static void session_setup_restart_command(void)
 {
     gint i;
 
@@ -370,7 +370,7 @@ static void session_setup_restart_command()
     g_free(vals);
 }
 
-static ObSMSaveData *sm_save_get_data()
+static ObSMSaveData *sm_save_get_data(void)
 {
     ObSMSaveData *savedata = g_new0(ObSMSaveData, 1);
     /* save the active desktop and client.
index e226f36..773f658 100644 (file)
@@ -43,7 +43,7 @@ extern GList *stacking_list;
 
 /*! Sets the window stacking list on the root window from the
   stacking_list */
-void stacking_set_list();
+void stacking_set_list(void);
 
 void stacking_add(struct _ObWindow *win);
 void stacking_add_nonintrusive(struct _ObWindow *win);
@@ -56,7 +56,7 @@ void stacking_raise(struct _ObWindow *window);
 void stacking_temp_raise(struct _ObWindow *window);
 
 /*! Restores any temporarily raised windows to their correct place */
-void stacking_restore();
+void stacking_restore(void);
 
 /*! Lowers a window below all others in its stacking layer */
 void stacking_lower(struct _ObWindow *window);
index 758beee..d524bca 100644 (file)
@@ -25,7 +25,7 @@
 void sn_startup(gboolean reconfig);
 void sn_shutdown(gboolean reconfig);
 
-gboolean sn_app_starting();
+gboolean sn_app_starting(void);
 
 /*! Notify that an app has started
   @param wmclass the WM_CLASS[1] hint
@@ -45,6 +45,6 @@ void sn_setup_spawn_environment(const gchar *program, const gchar *name,
 /* Tell startup notification we're not actually running the program we
    told it we were
 */
-void sn_spawn_cancel();
+void sn_spawn_cancel(void);
 
 #endif
index bd8b88f..71a919c 100644 (file)
@@ -166,7 +166,11 @@ gchar *translate_keycode(guint keycode)
 
     if ((sym = XKeycodeToKeysym(ob_display, keycode, 0)) != NoSymbol)
         ret = XKeysymToString(sym);
-    return g_locale_to_utf8(ret, -1, NULL, NULL, NULL);
+    /* glib crashes in g_locale_to_utf8 if you pass it NULL here */
+    if (ret)
+        return g_locale_to_utf8(ret, -1, NULL, NULL, NULL);
+    else
+        return NULL;
 }
 
 gunichar translate_unichar(guint keycode)
index 897d738..6db7ca7 100644 (file)
@@ -219,10 +219,12 @@ void parse_close(xmlDocPtr doc)
 void parse_tree(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
 {
     while (node) {
-        struct Callback *c = g_hash_table_lookup(i->callbacks, node->name);
+        if (node->name) {
+            struct Callback *c = g_hash_table_lookup(i->callbacks, node->name);
 
-        if (c)
-            c->func(i, doc, node, c->data);
+            if (c)
+                c->func(i, doc, node, c->data);
+        }
 
         node = node->next;
     }
@@ -231,7 +233,9 @@ void parse_tree(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
 gchar *parse_string(xmlDocPtr doc, xmlNodePtr node)
 {
     xmlChar *c = xmlNodeListGetString(doc, node->children, TRUE);
-    gchar *s = g_strdup(c ? (gchar*)c : "");
+    gchar *s;
+    if (c) g_strstrip((char*)c);
+    s = g_strdup(c ? (gchar*)c : "");
     xmlFree(c);
     return s;
 }
@@ -239,7 +243,9 @@ gchar *parse_string(xmlDocPtr doc, xmlNodePtr node)
 gint parse_int(xmlDocPtr doc, xmlNodePtr node)
 {
     xmlChar *c = xmlNodeListGetString(doc, node->children, TRUE);
-    gint i = c ? atoi((gchar*)c) : 0;
+    gint i;
+    if (c) g_strstrip((char*)c);
+    i = c ? atoi((gchar*)c) : 0;
     xmlFree(c);
     return i;
 }
@@ -248,6 +254,7 @@ gboolean parse_bool(xmlDocPtr doc, xmlNodePtr node)
 {
     xmlChar *c = xmlNodeListGetString(doc, node->children, TRUE);
     gboolean b = FALSE;
+    if (c) g_strstrip((char*)c);
     if (c && !xmlStrcasecmp(c, (const xmlChar*) "true"))
         b = TRUE;
     else if (c && !xmlStrcasecmp(c, (const xmlChar*) "yes"))
@@ -262,6 +269,7 @@ gboolean parse_contains(const gchar *val, xmlDocPtr doc, xmlNodePtr node)
 {
     xmlChar *c = xmlNodeListGetString(doc, node->children, TRUE);
     gboolean r;
+    if (c) g_strstrip((char*)c); /* strip leading/trailing whitespace */
     r = !xmlStrcasecmp(c, (const xmlChar*) val);
     xmlFree(c);
     return r;
@@ -282,6 +290,7 @@ gboolean parse_attr_bool(const gchar *name, xmlNodePtr node, gboolean *value)
     xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
     gboolean r = FALSE;
     if (c) {
+        g_strstrip((char*)c); /* strip leading/trailing whitespace */
         if (!xmlStrcasecmp(c, (const xmlChar*) "true"))
             *value = TRUE, r = TRUE;
         else if (!xmlStrcasecmp(c, (const xmlChar*) "yes"))
@@ -304,6 +313,7 @@ gboolean parse_attr_int(const gchar *name, xmlNodePtr node, gint *value)
     xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
     gboolean r = FALSE;
     if (c) {
+        g_strstrip((char*)c); /* strip leading/trailing whitespace */
         *value = atoi((gchar*)c);
         r = TRUE;
     }
@@ -316,6 +326,7 @@ gboolean parse_attr_string(const gchar *name, xmlNodePtr node, gchar **value)
     xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
     gboolean r = FALSE;
     if (c) {
+        g_strstrip((char*)c); /* strip leading/trailing whitespace */
         *value = g_strdup((gchar*)c);
         r = TRUE;
     }
@@ -328,8 +339,10 @@ gboolean parse_attr_contains(const gchar *val, xmlNodePtr node,
 {
     xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
     gboolean r = FALSE;
-    if (c)
+    if (c) {
+        g_strstrip((char*)c);
         r = !xmlStrcasecmp(c, (const xmlChar*) val);
+    }
     xmlFree(c);
     return r;
 }
index 28af64b..ccd4e45 100644 (file)
@@ -31,7 +31,7 @@ typedef struct _ObParseInst ObParseInst;
 typedef void (*ParseCallback)(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
                               gpointer data);
 
-ObParseInst* parse_startup();
+ObParseInst* parse_startup(void);
 void parse_shutdown(ObParseInst *inst);
 
 /*! Loads Openbox's rc, from the normal paths
@@ -77,13 +77,13 @@ gboolean parse_attr_bool(const gchar *name, xmlNodePtr node, gboolean *value);
 
 /* paths */
 
-void parse_paths_startup();
-void parse_paths_shutdown();
+void parse_paths_startup(void);
+void parse_paths_shutdown(void);
 
-const gchar* parse_xdg_config_home_path();
-const gchar* parse_xdg_data_home_path();
-GSList* parse_xdg_config_dir_paths();
-GSList* parse_xdg_data_dir_paths();
+const gchar* parse_xdg_config_home_path(void);
+const gchar* parse_xdg_data_home_path(void);
+GSList* parse_xdg_config_dir_paths(void);
+GSList* parse_xdg_data_dir_paths(void);
 
 /*! Expands the ~ character to the home directory throughout the given
   string */
index 1dde5fb..4663999 100644 (file)
@@ -1,12 +1,12 @@
 !# Clearlooks-Evolving
-!# Clearlooks as it evolves in gnome-svn...
-!# Last updated 19/01/08
+!# Clearlooks as it evolves in gnome-git...
+!# Last updated 09/03/10
 
 # Fonts
 # these are really halos, but who cares?
 
 *.font: shadow=n
-window.active.label.text.font:shadow=y:shadowtint=25:shadowoffset=1
+window.active.label.text.font:shadow=y:shadowtint=30:shadowoffset=1
 window.inactive.label.text.font:shadow=y:shadowtint=00:shadowoffset=0
 menu.items.font:shadow=y:shadowtint=0:shadowoffset=1
 
@@ -25,11 +25,11 @@ menu.overlap: 2
 *.bg.highlight: 50
 *.bg.shadow:    05
 
-window.active.title.bg.highlight: 40
-window.active.title.bg.shadow:    00
+window.active.title.bg.highlight: 35
+window.active.title.bg.shadow:    05
 
 window.inactive.title.bg.highlight: 30
-window.inactive.title.bg.shadow:    00
+window.inactive.title.bg.shadow:    05
 
 window.*.grip.bg.highlight: 50
 window.*.grip.bg.shadow:    30
@@ -61,6 +61,11 @@ menu.items.active.bg.colorTo.splitTo: #80a7d6
 menu.items.active.bg.border.color: #4b6e99
 menu.items.active.text.color: #ffffff
 
+menu.separator.width: 1
+menu.separator.padding.width: 0
+menu.separator.padding.height: 3
+menu.separator.color: #aaaaaa
+
 !# set handles here and only the once?
 
 window.*.handle.bg: Raised solid
@@ -71,9 +76,6 @@ window.*.grip.bg.color: #eaebec
 
 !# Active
 
-!# no handles - kind of closer to the clearlooks border, maybe?
-!#window.active.border.color: #455d7c
-
 window.*.border.color: #585a5d
 
 window.active.title.separator.color: #4e76a8
@@ -135,7 +137,7 @@ window.inactive.button.*.image.color: #6D6C6C
 !# osd (pop ups and what not, dock?)
 
 osd.border.width: 1
-osd.border.color:  #999
+osd.border.color:  #aaaaaa
 
 osd.bg: flat border gradient splitvertical
 osd.bg.color: #F0EFEE