Design Document Actions

From Openbox

(Difference between revisions)
Jump to: navigation, search
(Redirecting to Design Documents:Actions)
 
(7 intermediate revisions by one user not shown)
Line 1: Line 1:
This is a chronological brain dump from top to bottom, so should really be read from bottom up maybe.
+
#REDIRECT [[Design_Documents:Actions]]
 
+
* singleword = action
+
* key:value = set option for last seen action
+
* { } = for placing an action (or list of) in an action
+
* " " = is a string, not an action
+
* can use \\ \" \( and \) inside any string
+
== Filters ==
+
* [ ] = setting target(s) for an action, tries them left to right until it finds one that matches at least 1 window. separate target options by ",".  all options inside one set of [] must apply to choose a window.
+
**      some targets are:
+
***        target - is the focused window, or the window targetted by an interractive action
+
***        focus - is the focused window (ignores the fact you're targetting something else in alt-tab for instance
+
***        title="foo" - pattern match foo against all titles
+
***        type="foo" - pattern match foo against all types
+
***        (basically anything we test in the app-specific rules..)
+
***        desktop=1 - match against the window's current desktop (a number or "all")
+
***        ifviewing=3 - match against current desktop (filters all or none)
+
***        visible - a flag that the window is on the currently visible desktop
+
***        not<test> - inverts the other test  (maybe not <test>)
+
 
+
for bind action, chroot means when a breakchroot is hit, any bindings inside are removed
+
 
+
bind key:C-A-a chroot:yes actions:{ bind key:Escape actions:breakchroot
+
                                    bind key:Left actions:{moverelative x:-5}
+
                                    bind key:Right actions:{moverelative x:5}
+
                                    bind key:Up actions:{moverelative y:-5}
+
                                    bind key:Down actions:{moverelative y:5}
+
                                  }
+
 
+
we decided not to do chroots this way. '''WE DIDN'T DECIDE HOW TO REPRESENT THEM YET.''' or how to do keybindings in general.  the action approach seems decent though.
+
 
+
Possible -unixcommand syntax
+
bind -key=A-Tab -actions={nextwindow -finalactions={focus unshade raise -app=yes}}
+
 
+
Examples..
+
bind key:W-a actions:togglemaximizefull
+
bind key:A-Escape actions:{lower app:yes focustobottom unfocus}
+
bind key:A-Tab actions:{nextwindow finalactions:{focus unshade raise app:yes}}
+
bind key:A-S-Tab actions:{previouswindow finalactions:{focus unshade raise app:yes}}
+
bind key:W-Tab actions:{showmenu menu:client-list-combined-menu}
+
bind key:W-F10 actions:{execute command:"gnome-screensaver-command -l"}
+
bind key:W-F11 actions:reconfigure
+
bind key:W-F12 actions:restart
+
bind key:C-A-Left actions:{desktopleft dialog:no wrap:no}
+
bind key:C-A-Up actions:{desktopup dialog:no wrap:no}
+
bind key:S-A-Up actions:{sendtodesktopup dialog:no wrap:no follow:yes}
+
bind key:A-F4 actions:{close}
+
bind key:A-F4 actions:{close [target]}  # target = default
+
bind key:A-S-F4 actions:{close [title="*Google Chrome", desktop=2]}  # chrome windows on desktop 2
+
bind key:A-S-F4 actions:{close [desktop=1] [desktop=2]}  # all windows on desktop 1. if none match, then all windows on desktop 2
+
bind key:Print actions:{execute command:"gnome-screenshot"}
+
bind key:W-d actions:{toggleshowdesktop}
+
bind key:W-S-Right actions:{directionalcyclewindows direction:right}
+
bind key:W-S-Left  actions:{directionalcyclewindows direction:left}
+
bind key:W-S-Up    actions:{directionalcyclewindows direction:up}
+
bind key:W-S-Down  actions:{directionalcyclewindows direction:down}
+
 
+
reconfigure  # an action with no options
+
restart command:"metacitylol"  # an action with one option
+
nextwindow finalactions:{focus unshade raise app:yes}  # nested actions
+
# execute action outside of a bind action
+
execute startupnotify:true startupname:Konqueror command:"kfmclient openProfile filemanagement"  # multiple options
+
 
+
close [target]   # target = default
+
close [title="*Google Chrome", desktop=2]  # chrome windows on desktop 2
+
close [desktop=1] [desktop=2]  # all windows on desktop 1. if none match, then all windows on desktop 2
+
 
+
togglemaximizefull
+
moverelative x:-5
+
moverelative y:-5
+
moverelative y:-5
+
moverelative y:-5
+
 
+
Have alias action to build composite actions (macros)
+
alias name:_foo actions:{foo bar baz}
+
 
+
if [title="* GIMP", desktop=8, viewing=8] actions:{foo bar}
+
 
+
alias name:_myif actions:
+
  [viewing=8, desktop=8] {
+
    [title="* GIMP"] {
+
      moveresizeto x:69 y:0 width:1373 height:1005
+
      sendkeyevent usetarget:no key:C-j
+
    }
+
    [locked=no, notitle="* GIMP" title="Toolbox - *"]
+
      lock
+
  }
+
 
+
Attempt at an Else:
+
[viewing=8, desktop=8] {
+
  [title="* GIMP"] nextwindow
+
}
+
| [visible] nextwindow
+
 
+
alias name:_myif actions:{
+
  moveresizeto [viewing=8, desktop=8, title="* GIMP"] x:69 y:0 width:1373 height:1005
+
  sendkeyevent [viewing=8, desktop=8, title="* GIMP"] usetarget:no key:C-j
+
  lock        [locked=no notitle="* GIMP" title="Toolbox - *"]}
+
}
+
 
+
Attempt to group filters on actions by use of a chain action:
+
chain [viewing=8,desktop=8] a:{chain [title="* GIMP"] a:{moveresizeto x:69 y:0 width:1373 height:1005 sendkeyevent usetarget:no key:C-j} | lock [locked=no, title="Toolbox - *]}
+
 
+
[target] {moveresizeto a:foo} | stuff
+
[desktop=2] movetodesktop desktop:4 | [desktop=1] {stuff otherstuff}
+
[foo] bar | baz
+
 
+
Do filters stack as parsing continues on a line?  We decided no.
+
 
+
What about OR in filters?
+
[foo] bar | [lal] bar | baz => [foo | lal] bar | baz
+
 
+
[a,b | c,d] foo | bar
+
[a, (b|c), d] foo | bar
+
 
+
= PROPOSED ACTION LANGUAGE =
+
 
+
In BNF like thing:
+
TEST      := KEY=VALUE | KEY  # eg. locked or desktop=1. See [[#Filters|Filters]].
+
ACTION    := [FILTER] ACTION | ACTIONNAME ACTIONOPTS ELSE | {ACTIONLIST}
+
ACTIONLIST := ACTION ACTIONLIST | ACTION
+
ELSE      := nil | \| ACTION
+
FILTER    := FILTERORS
+
FILTERORS  := FILTERANDS \| FILTERORS | FILTERANDS
+
FILTERANDS := TEST, FILTERANDS | TEST
+
ACTIONOPTS := ACTIONOPT ACTIONOPTS | ACTIONOPT
+
ACTIONOPT  := ATTRIBUTE:TEXTWORD | ATTRIBUTE:TEXTSTRING | ATTRIBUTE:{ACTIONLIST}
+
TEXTWORD  := strings not starting with " or ( or {
+
TEXTSTRING := "TEXT" | (TEXT) where TEXT is a string, where ')' or '"' (depending how it is quoted) must be escaped by an '\'. \\ \( \) and \" are all valid escaped characters.
+
 
+
In English like thing:
+
an ACTIONSPOT can hold an ACTION, an ACTIONLIST, or a FILTER. it may be followed by a | ELSE, where ELSE is an ACTIONSPOT which is only run if the prior action spot's filter returned an empty list of windows.
+
an ACTIONLIST is a list of 1 or more space-separated ACTIONSPOTS inside {}.
+
a FILTER is a [] with tests (eg foo=bar) inside delimited by , for AND and | for OR. AND has higher precedence, followed by an ACTIONSPOT.
+
an ACTION is a name (no spaces) and a space-separated list of key:value pairs to assign to the ACTION.  the value is a WORD, a STRING or an ACTIONLIST.
+
a WORD is a string of text with no space and does not start with a '(' '"' or '{' character.
+
a STRING is a string of text quoted with "" or ().  the ending quoting character and '\' must be escaped inside the STRING, and \( \) \" or \\ are all valid escaped characters.
+
  Unrecognized escape sequences are simply dropped from the string with a warning to the user.
+
 
+
Example using bind to also be an action:
+
bind key:M-r actions:{[la] foo | {bar etc:(yay)}
+
                      morethings
+
                      }
+
 
+
Bind actions should not persist though! Need to be recreated at startup, tho they can be injected at runtime.
+
 
+
note: OR precedence can be achived by splitting into nested filters:
+
  [a,b] [c|d] foo  => if a&b&(c|d) then foo
+
 
+
Examples:
+
execute startupnotify:true startupname:Konqueror command:(kfmclient openProfile filemanagement)
+
execute startupnotify:true startupname:Konqueror command:"kfmclient openProfile filemanagement"
+
 
+
[ifviewing=8, desktop=8] {
+
  [title="* GIMP"] {moveresize sendkey}
+
  [title="Toolbox - *", nottitle="* GIMP", locked=no] lock
+
}
+
 
+
== Functionality ==
+
 
+
[[#Filters|Filters]] are used to create a list of windows.  The default filter is ''[target]'' meaning only the targetted window is matched.  Each action is run and passed a list of windows matched by the filters applied to it.
+
 
+
== Keybindings, Mousebindings and Lions, Oh my. ==
+
 
+
We need to decide
+
1) how to do keybinds, esp chroots.
+
2) how to do mousebinds, esp contexts (no xml tree anymore)
+

Latest revision as of 13:45, 26 July 2011

  1. REDIRECT Design_Documents:Actions
Personal tools