You are not logged in.

#1 2011-05-15 09:19:24

ans5685
Member
From: Kolkata/India
Registered: 2008-07-02
Posts: 14

Script for Window tiling in openbox

I wanted to use a tiling window manager but didn't want to leave openbox. So I started using PyTyle and PyTyle2 but they both took up more RAM than I could afford to let them use in my lowly desktop. So I wrote a script to do my tiling for me using wmctrl and xwininfo. And here are the results:
GRID mode:
2011-05-15-132903_288x162_scrot-thumb.png

BOTTOM MASTER mode:

2011-05-15-132933_288x162_scrot-thumb.png

TOP MASTER mode:

2011-05-15-133000_288x162_scrot-thumb.png

LEFT MASTER mode (also the default) :

2011-05-15-133033_288x162_scrot-thumb.png

RIGHT MASTER mode:

2011-05-15-133358_288x162_scrot-thumb.png

MAX mode:
2011-05-15-133426_288x162_scrot-thumb.png

HORIZONTAL SPLIT mode:

2011-05-15-133450_288x162_scrot-thumb.png

VERTICAL SPLIT  mode :

2011-05-15-133510_288x162_scrot-thumb.png


The entire thing is just one bash script that I named wmtiler.sh



The script itself is rather poorly written as I don't have much experience in bash. sad

#!/bin/bash
# use wmctrl and xwininfo to tile windows
#currently supports the "LEFT_MASTER" mode  (default),
# "RIGHT_MASTER" mode (-r) , 
# "TOP_MASTER" mode (-t), 
#"BOTTOM_MASTER" mode (-b) ,
#"GRID" mode (-g), 
#"MAX" mode (-m) ,
# "VERTICAL_SPLIT" mode (-v)  and
#"HORIZONTAL_SPLIT"  mode (-h)

#NOTE: wmctrl sets the properties of the window itself i.e. the window manager's borders 
#and title bars are not taken into account while setting the coordinates. So for best results 
#set the window manager to display all windows undecorated 
#or manually set the title bar height here

#List of things to do:
# 1.    Get the values of the TOP_MARGIN, BOTTOM_MARGIN, LEFT_MARGIN and RIGHT_MARGIN from the window manager
# 2.    Get the MASTER_WIDTH for the default LEFT_MASTER, RIGHT_MASTER layouts as a parameter , set a default if not provided
# 3.    Get the MASTER_HEIGHT for the default TOP_MASTER, BOTTOM_MASTER layouts as a parameter , set a default if not provided
# 4.    Get the NUMBER_OF_ROWS for the grid mode as a parameter, set a default if not provided
# 5.    Get the  TITLE_BAR_HEIGHT from the window manager
# 6.     Restructure the code to use functions
# 7.     Provide mechanisms to increase/decrease the MASTER area
# 8.    Provide mechanisms to increase/decrease the number of windows in the MASTER area

#List of bugs
# 1.    If called from a key combination, there may not be a :ACTIVE: window and in which case the results are not as desired. 
# 2.    The title bar plays havoc with the height of windows  

#need to find a way to get these from the window manager
TOP_MARGIN=18
BOTTOM_MARGIN=18
LEFT_MARGIN=0
RIGHT_MARGIN=0
TITLE_BAR_HEIGHT=17 #works best if all the windows are border less and this is set to zero

#we are now using xwininfo to get these
#HEIGHT=1080
#WIDTH=1920

#either set these in a file or calculate them from the screen properties
MASTER_WIDTH=1344
MASTER_HEIGHT=600
#set the number of rows we want for the grid mode 
NUMBER_OF_ROWS=2
#looks nice :)
USELESS_GAPS=1

#see what the user wants to do
case $1 in 
"-g")
        MODE="GRID"
        ;;
"-m")
        MODE="MAX"
        ;;                
"-v")
        MODE="VERTICAL_SPLIT"
        ;;                
"-h")
        MODE="HORIZONTAL_SPLIT"
        ;;                
"-t")
        MODE="TOP_MASTER"
        ;;
"-b")
        MODE="BOTTOM_MASTER"
        ;;        
"-r")
        MODE="RIGHT_MASTER"
        ;;                

*)    
        MODE="LEFT_MASTER"
        ;;
esac


#get the desktop parameters
HEIGHT=`xwininfo -root | grep 'Height:' | awk '{print $2}'`
WIDTH=`xwininfo -root | grep 'Width:' | awk '{print $2}'`


#get the window parameters
    
#get the current desktop
CURR_DESK=` wmctrl -d | grep '* DG:'| awk '{print $1}'`

#get the total number of windows.
#NOTE: we are not directly using grep to get the windows from the current desktop as it may serve up some false positives
TOTAL_WINDOWS=`wmctrl -lx | wc -l`
#counter
i=1
#Assume that there are no windows in the current desktop
WINDOWS_IN_DESK=0
while  [ $i  -le  $TOTAL_WINDOWS ] ; do
    CURR_LINE=`wmctrl -lx | head -n $i | tail -n 1`
    WIN_DESK=`echo $CURR_LINE | awk '{print $2}'`
    if  [ $WIN_DESK  -eq  $CURR_DESK ] ; then
    #save the various window properties as supplied by wmctrl . Un comment rest if necessary. Include more if necessary
        WIN_XID[$WINDOWS_IN_DESK]=`echo $CURR_LINE | awk '{print $1}'`
    #    WIN_XOFF[$WINDOWS_IN_DESK]=`echo $CURR_LINE | awk '{print $2}'`
    #    WIN_YOFF[$WINDOWS_IN_DESK]=`echo $CURR_LINE | awk '{print $3}'`
    #    WIN_WIDTH[$WINDOWS_IN_DESK]=`echo $CURR_LINE | awk '{print $4}'`
    #    WIN_HEIGHT[$WINDOWS_IN_DESK]=`echo $CURR_LINE | awk '{print $5}'`
    
    #see if the window is "IsViewable" or "IsUnMapped" i.e minimized
        MAP_STATE=`xwininfo -id ${WIN_XID[$WINDOWS_IN_DESK]} | grep "Map State:" | awk '{print $3}'`
    #we don't  want the minimized windows to be considered while allocating the space
        if [ "$MAP_STATE"  ==  "IsViewable" ]; then
            WINDOWS_IN_DESK=$((WINDOWS_IN_DESK+1))
        fi    
    fi
    i=$((i+1))
done

#get the xid of the active window. 
ACTIVE_WIN=`xprop -root | awk '/_NET_ACTIVE_WINDOW\(WINDOW\)/{print $NF}'`


#set the selected layout
#NOTE: these would look better if they were individual functions :)
case $MODE in 

"LEFT_MASTER")
            #define the properties of the master area
            X=$LEFT_MARGIN
            Y=$TOP_MARGIN
            #set the width to the default MASTER_WIDTH 
            W=$MASTER_WIDTH
            H=$(( HEIGHT -TOP_MARGIN - BOTTOM_MARGIN -TITLE_BAR_HEIGHT -USELESS_GAPS))
            #set the active window to the "master "area
            wmctrl    -r :ACTIVE: -e "0,$X,$Y,$W,$H"

             #now that the master window has been set all further windows would have to start from here
              X=$((MASTER_WIDTH+USELESS_GAPS))
             #get whatever width is left
             W=$((WIDTH - MASTER_WIDTH -USELESS_GAPS))
             #the height would be equally shared by the rest of the windows
             H=$((H/(WINDOWS_IN_DESK - 1) - TITLE_BAR_HEIGHT -USELESS_GAPS ))
             i=0
              while  [ "$i"  -le  "$WINDOWS_IN_DESK" ] ;  do
                #avoid setting the attributes of the active window again
                if  [[ "${WIN_XID[$i]}" -ne "$ACTIVE_WIN" ]] ; then
                #set the attributes 
                    wmctrl  -i  -r ${WIN_XID[$i]} -e "0,$X,$Y,$W,$H"
                    #set the Y co-ordinate for the next window.
                    
                    Y=$((Y+H+TITLE_BAR_HEIGHT+USELESS_GAPS))
                fi
                #preselect the next window
                i=$((i+1))
             done
             ;;

"RIGHT_MASTER")
            #define the properties of the master area
            X=$LEFT_MARGIN
            Y=$TOP_MARGIN
             #get whatever width is left
             W=$((WIDTH - MASTER_WIDTH -USELESS_GAPS))
             #the height would be equally shared by the non master windows
             H=$(((HEIGHT -TOP_MARGIN -BOTTOM_MARGIN  )/(WINDOWS_IN_DESK-1) -TITLE_BAR_HEIGHT -USELESS_GAPS))
             i=0
              while  [ "$i"  -le  "$WINDOWS_IN_DESK" ] ;  do
                #avoid setting the attributes of the active window 
                if  [[ "${WIN_XID[$i]}" -ne "$ACTIVE_WIN" ]] ; then
                #set the attributes 
                    wmctrl  -i  -r ${WIN_XID[$i]} -e "0,$X,$Y,$W,$H"
                    #set the Y co-ordinate for the next window.
                    
                    Y=$((Y+H+TITLE_BAR_HEIGHT+USELESS_GAPS))
                fi
                #preselect the next window
                i=$((i+1))
            done
            #set the co-ordinates for the  MASTER_WINDOW
            X=$((W+USELESS_GAPS))
            Y=$TOP_MARGIN
            W=$MASTER_WIDTH
            H=$(( HEIGHT -TOP_MARGIN - BOTTOM_MARGIN -TITLE_BAR_HEIGHT -USELESS_GAPS))
            #set the active window to the "master "area
            wmctrl    -r :ACTIVE: -e "0,$X,$Y,$W,$H"

             ;;             
"TOP_MASTER")
            #define the properties of the master area
            X=$LEFT_MARGIN
            Y=$TOP_MARGIN
            #set the width taking into acount the margins
            W=$((WIDTH-LEFT_MARGIN-RIGHT_MARGIN))
            H=$MASTER_HEIGHT
            #set the active window to the "master "area
            wmctrl    -r :ACTIVE: -e "0,$X,$Y,$W,$H"

             #set the y co-ordinate
             Y=$((Y+H+USELESS_GAPS+TITLE_BAR_HEIGHT))
             #Distribute the  width amon the remaining windows
              W=$((W/(WINDOWS_IN_DESK-1)))
              #set the  new height
             H=$((HEIGHT-MASTER_HEIGHT-TOP_MARGIN-BOTTOM_MARGIN-TITLE_BAR_HEIGHT-USELESS_GAPS))
             
             i=0
              while  [ "$i"  -le  "$WINDOWS_IN_DESK" ] ;  do
                #avoid setting the attributes of the active window again
                if  [[ "${WIN_XID[$i]}" -ne "$ACTIVE_WIN" ]] ; then
                #set the attributes 
                    wmctrl  -i  -r ${WIN_XID[$i]} -e "0,$X,$Y,$W,$H"
                    #set the X co-ordinate for the next window.
                    X=$((X+W+USELESS_GAPS))
                fi
                #preselect the next window
                i=$((i+1))
             done
             ;;
"BOTTOM_MASTER")
            #define the properties of the master area
            X=$LEFT_MARGIN
            Y=$TOP_MARGIN

             #Distribute the  width among the non master windows
              W=$(((WIDTH-LEFT_MARGIN-RIGHT_MARGIN)/(WINDOWS_IN_DESK-1)))
              #set the  new height
             H=$((HEIGHT-MASTER_HEIGHT-TOP_MARGIN-BOTTOM_MARGIN-TITLE_BAR_HEIGHT-USELESS_GAPS))
             
             i=0
              while  [ "$i"  -le  "$WINDOWS_IN_DESK" ] ;  do
                #avoid setting the attributes of the active window again
                if  [[ "${WIN_XID[$i]}" -ne "$ACTIVE_WIN" ]] ; then
                #set the attributes 
                    wmctrl  -i  -r ${WIN_XID[$i]} -e "0,$X,$Y,$W,$H"
                    #set the X co-ordinate for the next window.
                    X=$((X+W+USELESS_GAPS))
                fi
                #preselect the next window
                i=$((i+1))
             done
             #set the  co-ordinates
             X=$LEFT_MARGIN
             Y=$((Y+H+USELESS_GAPS+TITLE_BAR_HEIGHT))
             W=$((WIDTH-LEFT_MARGIN-RIGHT_MARGIN))
             H=$MASTER_HEIGHT
            #set the active window to the "master "area
            wmctrl    -r :ACTIVE: -e "0,$X,$Y,$W,$H"
             ;;
                 
                          
"GRID")
            #find the number of windows in the top row and in each subsequent row except for the bottom row. 
            NORMAL_ROW_WINDOWS=$((WINDOWS_IN_DESK/NUMBER_OF_ROWS))
            #the bottom row ould have as many windows as the top row and any left over
            BOTTOM_ROW_WINDOWS=$((NORMAL_ROW_WINDOWS + WINDOWS_IN_DESK%NUMBER_OF_ROWS))
            WINDOWS_NOT_IN_BOTTOM_ROW=$((WINDOWS_IN_DESK-BOTTOM_ROW_WINDOWS))
            #set the co-ordinates for the top row
            X=$LEFT_MARGIN
            Y=$TOP_MARGIN
            #the height of each window would remain the same regardless of which row it is in
            H=$(((HEIGHT-TOP_MARGIN-BOTTOM_MARGIN)/NUMBER_OF_ROWS - TITLE_BAR_HEIGHT))
            #Find the width of each window in the top row, this would be the same for each row except for the bottom row which may contain more windows
            NORMAL_ROW_WIDTH=$((((WIDTH-LEFT_MARGIN-RIGHT_MARGIN)/NORMAL_ROW_WINDOWS)-USELESS_GAPS*NORMAL_ROW_WINDOWS))
            BOTTOM_ROW_WIDTH=$((((WIDTH-LEFT_MARGIN-RIGHT_MARGIN)/BOTTOM_ROW_WINDOWS)-USELESS_GAPS*NORMAL_ROW_WINDOWS))
            #start counting from zero
            i=0
            #we havent processed any windows yet
            CURRENT_ROW_WINDOWS=0
            #we will be processing the 1st row
            CURRENT_ROW=1
            while  [ "$i"  -le  "$WINDOWS_IN_DESK" ] ;  do
                if  [[ "$CURRENT_ROW" -lt "$NUMBER_OF_ROWS" ]]; then
                    if [[ "$CURRENT_ROW_WINDOWS" -eq "NORMAL_ROW_WINDOWS " ]]; then 
                        CURRENT_ROW=$((CURRENT_ROW+1))
                        if [[ "$CURRENT_ROW" -eq "$NUMBER_OF_ROWS" ]] ; then 
                            X=$LEFT_MARGIN
                            Y=$((Y+H+TITLE_BAR_HEIGHT+USELESS_GAPS))
                            W=$BOTTOM_ROW_WIDTH
                        else
                            CURRENT_ROW_WINDOWS=0
                        fi    
                    fi
                    if [[ "$CURRENT_ROW_WINDOWS" -eq "0" ]] ; then
                        X=$LEFT_MARGIN
                        W=$NORMAL_ROW_WIDTH
                        if [[ "$CURRENT_ROW" -ne "1" ]]; then
                            Y=$((Y+H+TITLE_BAR_HEIGHT+USELESS_GAPS))
                        fi    
                    fi        
                fi
                wmctrl  -i  -r ${WIN_XID[$i]} -e "0,$X,$Y,$W,$H"
                X=$((X+W+USELESS_GAPS))
                CURRENT_ROW_WINDOWS=$((CURRENT_ROW_WINDOWS+1))
                i=$((i+1))
            done
            
            ;;    
"MAX")
                X=$LEFT_MARGIN
                Y=$TOP_MARGIN
                H=$((HEIGHT-TOP_MARGIN-BOTTOM_MARGIN))
                W=$((WIDTH-LEFT_MARGIN-RIGHT_MARGIN))
                i=0
                 while  [ "$i"  -le  "$WINDOWS_IN_DESK" ] ;  do
                #avoid setting the attributes of the active window 
                if  [[ "${WIN_XID[$i]}" -ne "$ACTIVE_WIN" ]] ; then
                #set the attributes 
                    wmctrl  -i  -r ${WIN_XID[$i]} -e "0,$X,$Y,$W,$H"
                fi
                #preselect the next window
                i=$((i+1))
             done
             #now that all the windows have been set set the master on top
             wmctrl    -r :ACTIVE: -e "0,$X,$Y,$W,$H"
             ;;
"VERTICAL_SPLIT")
                X=$LEFT_MARGIN
                Y=$TOP_MARGIN
                H=$((HEIGHT-TOP_MARGIN-BOTTOM_MARGIN))
                W=$(((WIDTH-LEFT_MARGIN-RIGHT_MARGIN)/WINDOWS_IN_DESK - USELESS_GAPS))
                i=0
                while  [ "$i"  -le  "$WINDOWS_IN_DESK" ] ;  do
                    wmctrl  -i  -r ${WIN_XID[$i]} -e "0,$X,$Y,$W,$H"
                    #preselect the next window
                    X=$((X+W+USELESS_GAPS))
                    i=$((i+1))
                done
             ;;             
"HORIZONTAL_SPLIT")
                X=$LEFT_MARGIN
                Y=$TOP_MARGIN
                H=$(((HEIGHT-TOP_MARGIN-BOTTOM_MARGIN)/WINDOWS_IN_DESK -TITLE_BAR_HEIGHT -USELESS_GAPS))
                W=$((WIDTH-LEFT_MARGIN-RIGHT_MARGIN))
                i=0
                while  [ "$i"  -le  "$WINDOWS_IN_DESK" ] ;  do
                    wmctrl  -i  -r ${WIN_XID[$i]} -e "0,$X,$Y,$W,$H"
                    #preselect the next window
                    Y=$((Y+H+TITLE_BAR_HEIGHT+USELESS_GAPS))
                    i=$((i+1))
                done
             ;;                 
esac
 #say bye
 exit 0
 

I call the script using the openbox key bindings for example:

    <keybind key="W-g">
      <action name="Execute">
        <command>/home/default/bin/wmtiler.sh -g</command>
      </action>
    </keybind> 

The advantage this holds, in my case, is that it provides me with on demand automatic tiling with a momentary spike in CPU usage but no sustained RAM usage.

This should work on all window managers in which wmctrl works.

Of course  there are plenty of things still to do and many bugs to fix, some of which are documented in the script itself smile

Nothing would make me happier if somebody else found this useful. big_smile

Offline

#2 2011-05-15 12:40:21

kgas
Member
From: Qatar
Registered: 2008-11-08
Posts: 718

Re: Script for Window tiling in openbox

Thanks for your work.But the window resizing in vertical mode needs some work.For eg when chromium and terminals are open wmtiler -v put the terminal on the top of chromium and chromium is not getting resized.

Offline

#3 2011-05-15 13:12:29

ans5685
Member
From: Kolkata/India
Registered: 2008-07-02
Posts: 14

Re: Script for Window tiling in openbox

Could you post a screenshot of the problem? I couldn't replicate it  from what you said. Technically if you mention the TITLE_BAR_HEIGHT and use chromium without system borders then there is going to be a mismatch in the height. Also I tried to make the script generic but i haven't yet tested it on different monitor resolutions, so there should be more bugs than I have come across :(

Offline

#4 2011-05-15 13:14:00

demian
Member
From: Frankfurt, Germany
Registered: 2009-05-06
Posts: 709

Re: Script for Window tiling in openbox

Hey, thanks for writing a script like that. Openbox needs a little love in the department auf ondemand tiling.
I know of only one other script like yours, it's written in python2 and called 'simple window tiler' or stiler - an arch contribution too, but no longer developed.

But to get back to your script, for me, the following layouts work flawlessly (most of the time tongue):
horizontal_split
vertical_split
grid
max

However, the "master" layouts don't. I've attached screenshots:
left_master http://i52.tinypic.com/t7ettz.jpg
right_master http://i51.tinypic.com/25herg3.jpg
bottom_master http://i56.tinypic.com/2rxtjlc.jpg
top_master  http://i55.tinypic.com/swg6r5.jpg

As you can see, one window doesn't get tiled with the others. Also, left/right and top/bottom are identical.

My settings:

TOP_MARGIN=0
BOTTOM_MARGIN=0
LEFT_MARGIN=0
RIGHT_MARGIN=0
TITLE_BAR_HEIGHT=0
#we are now using xwininfo to get these
#HEIGHT=1080
#WIDTH=1920

#either set these in a file or calculate them from the screen properties
#MASTER_WIDTH=700
#MASTER_HEIGHT=450
#set the number of rows we want for the grid mode 
NUMBER_OF_ROWS=2
#looks nice :)
USELESS_GAPS=0

wmtiler also seems to have trouble with maximized windows, for instance maximized windows sometimes won't be tiled. some  other random occurences:
* two windows were killed while trying to switch to grid from a maximized window (the maximized one survived and went to the proper place in the grid layout, the other two were gone)
* one window was locked vertically. It used the whole width and i could not resize it. only move it up and down, not left or right or anything inbetween.
* one time, urxvt showed

I assume these are mostly bugs with wmctrl/xdotool but you might want to know about them.

Regards,
demian

P.S.:
Just adding some pictures of the 4 working layouts. I like pictures.
vertical http://i51.tinypic.com/jucm4o.jpg
horizontal http://i54.tinypic.com/rrs961.jpg 
grid http://i55.tinypic.com/2h58rno.jpg
max http://i51.tinypic.com/33nc20n.jpg

Last edited by demian (2011-05-15 23:57:22)


no place like /home
github

Offline

#5 2011-05-15 16:35:11

ans5685
Member
From: Kolkata/India
Registered: 2008-07-02
Posts: 14

Re: Script for Window tiling in openbox

I see that you have the master width and master height values commented out

 #MASTER_WIDTH=700
#MASTER_HEIGHT=450 

Did the tiling fail with these un-commented too? Currently the script requires these parameters to be set manually as I haven't yet got round to incorporating the increase/decrease master area by x% functions.

Regarding the maximized windows not being tiled, I noticed this bug after my initial post. I think wmctrl can be used to fix this. I'll get back to you as soon as I can get it working.
EDIT: Hopefully fixed! Please try it now : wmtiler.sh

Regarding the other issues, could you give me a bit more details as to what windows were open etc, so that I can  try to replicate and hopefully fix the bugs.

Last edited by ans5685 (2011-05-15 16:48:42)

Offline

#6 2011-05-15 17:12:44

demian
Member
From: Frankfurt, Germany
Registered: 2009-05-06
Posts: 709

Re: Script for Window tiling in openbox

I'll keep on using wmtiler and see if i can put together more elaborate "bug reports". What kind of information exactly would help besides the description? Logs, command outputs?

As for the master thing i feel really stupid now. I should have tried uncommenting them. Now the master layouts work, too.

In the last few minutes of using the new version with various layouts with varying amounts of windows open I didn't run into any bugs so I guess that's good. Tiling maximised windows works too now.

If you take feature requests, I really miss the following features compared to xmonad/awesome etc:
* untiling of all windows
* increasing/decreasing amount of master windows
* increasing/decreasing width/height of master window
* tiling just the focused window to 50% of the screen width at max height (like windows 7 does when you move a window over left/right screen edge). it's actually the tiling feature i use the most and something i miss in tiling window managers. it can be done with stiler though so there's no need to have it in wmtiler too - unless you want to of course.
This is what that would look like:
left http://i53.tinypic.com/144aip.jpg
right http://i56.tinypic.com/2lmsxn6.jpg

Regards,
demian

P.S.: Regarding the bugs i described in the previous post. I never had more than 3 windows open. One of them was always firefox, one other rxvt-unicode and the last one was either pcmanfm, medit or another instance of rxvt-unicode.

One bug(?) I noticed just now is that iconified windows won't get tiled. However, they still get taken into account so they occupy space but don't show up.

Last edited by demian (2011-05-15 18:52:51)


no place like /home
github

Offline

#7 2011-05-16 01:23:21

ans5685
Member
From: Kolkata/India
Registered: 2008-07-02
Posts: 14

Re: Script for Window tiling in openbox

Hmmm.... iconified windows should be totally ignored. Could you post the output of xwininfo for the iconified window? for example;

Get tet a list of windows open by issuing the wmctrl -lxG command

 
[default@arch_desktop ~]$ wmctrl -lxG
0x01400001 -1 4    0    1911 26   Conky.Conky           arch_desktop conky
0x01a00024  0 1346 52   576  254  surf.surf             arch_desktop 24Online Client
0x0200066a  1 1345 54   569  483  terminal.Terminal     arch_desktop Terminal - default@arch_desktop:~
0x02001231  1 1345 538  569  483  terminal.Terminal     arch_desktop Terminal - default@arch_desktop:~
0x02200004 -1 0    971  1920 109  avant-window-navigator.Avant-window-navigator  arch_desktop avant-window-navigator
0x01200039  1 0    18   1344 1026 chromium.Chromium     arch_desktop Post a reply / Arch Linux Forums - Chromium
0x0200279f  0 2    52   933  431  terminal.Terminal     arch_desktop Terminal - default@arch_desktop:~

and taking the window x id of the minimized surf window and issuing the xwininfo command:

[default@arch_desktop ~]$ xwininfo -id 0x01a00024

xwininfo: Window id: 0x1a00024 "24Online Client"

  Absolute upper-left X:  1345
  Absolute upper-left Y:  34
  Relative upper-left X:  1
  Relative upper-left Y:  18
  Width: 576
  Height: 254
  Depth: 24
  Visual: 0x21
  Visual Class: TrueColor
  Border width: 0
  Class: InputOutput
  Colormap: 0x20 (installed)
  Bit Gravity State: NorthWestGravity
  Window Gravity State: NorthWestGravity
  Backing Store State: NotUseful
  Save Under State: no
  Map State: IsUnMapped
  Override Redirect State: no
  Corners:  +1345+34  --1+34  --1-792  +1345-792
  -geometry 576x254--2+16

As you can see, for me , the "Map State:" is  "IsUnMapped" for the iconified windows and this set of commands is exactly what I am doing to ignore iconified windows. What I need to know is that is there some other type of map state that I need to ignore.


As for the feature requests I already had it in my mind to do the first three points that you mentioned. Since the script is intentionally designed not to run as a background process, there has to be some sort of a backing store like maybe a simple text file in which to save the state and read it from there on the next command invocation. The advantage would be it would take a momentary spike in CPU utilization and no sustained RAM utilization like I mentioned before. Disadvantage being the user would have to issue a command to actually get the tiling done.

Regarding your fourth point, did you mean setting the window to 50% width automatically on moving it to the screen edge like it is done in KWIn and Win7? If you want it to be done automatically then that would involve tracking the movement of the mouse and windows on the screen continuously. This is something I'd rather do in some other, tinier faster, script and call this script from that on specific events.
However, if you are willing to press a key while focused on a window and have it resized to max height and 50% of screen width either on the right side or on the left side, depending on the key combination, while leaving the other windows unaffected, then that can be arranged very simply.  smile

Offline

#8 2011-05-16 02:55:53

demian
Member
From: Frankfurt, Germany
Registered: 2009-05-06
Posts: 709

Re: Script for Window tiling in openbox

I think i figured out how the "iconify" bug worked for me.

A. First part

I. Steps to reproduce
  1. Open at least two windows
  2. Tile them at least once
  3. Open a new window
  4. Iconify that window
  5. Now tile a few times, with different layouts

II. The last opened window, when restored, should now be somewhere at a bottom corner of the screen, with only the top third visible.

B. Second part
If you have just one open window and you tile it with any other layout than max all, vertical_split or horizontal split the window will only occupy the master space. I assumed a different behaviour which is maximizing the window to use the whole screen.
So what must have happened is that i had 1 window open, then opened another one, which I iconified. Then the "bug" described in A. occured where the iconified window would move to the bottom right corner of the screen, resized to fit the slave part of the screen (as opposed to the master part). When I moved it i noticed it fit the slave space perfectly and assumed the tiling had gone wrong.

Here's xwininfo before and after:
before http://pastebin.com/UYDb1tEZ
after http://pastebin.com/2zampM4k

ans5685 wrote:

However, if you are willing to press a key while focused on a window and have it resized to max height and 50% of screen width either on the right side or on the left side, depending on the key combination, while leaving the other windows unaffected, then that can be arranged very simply.

Yup, that's what i meant. It works quite nicely in combination with

<followMouse>yes</followMouse>

It's very handy for any master layout as you just have to move your mouse over the window you want as master then press the hotkey for the desired layout.

P.S.:
If I could make one more suggestion for a feature it would be to swap windows (meaning place as well as size get swapped with the window that's focused while calling the function).

Last edited by demian (2011-05-16 03:20:46)


no place like /home
github

Offline

#9 2011-05-16 15:52:03

ans5685
Member
From: Kolkata/India
Registered: 2008-07-02
Posts: 14

Re: Script for Window tiling in openbox

Fixed the bug!! Thanks for the detailed description. Hopefully the fix didn't introduce any new bug.
Latest version : wmtiler.sh

The latest version also contains the ACTIVE_LEFT (wmtiler.sh -q) and ACTIVE_RIGHT (wmtiler.sh -e) modes that you asked for. ACTIVE_LEFT simply puts the currently active window to the left part of the screen taking up max height minus any margins and 50% of the available width, while leaving the other windows unaffected. ACTIVE_RIGHT does the same on the right.


demian wrote:

It's very handy for any master layout as you just have to move your mouse over the window you want as master then press the hotkey for the desired layout.

All the master layouts already behave in the way you mentioned smile

demian wrote:

If I could make one more suggestion for a feature it would be to swap windows (meaning place as well as size get swapped with the window that's focused while calling the function).

Well, currently. the focused window would get to be the master while the previous master would be put somewhere in the slave area depending on the order in which wmctrl reports it. Which I guess is kind of what you are asking for. Unless of course you want just the two of them to be swapped while leaving the others unaffected.

Any other suggestions?

Regards,
Animesh

Offline

#10 2011-05-16 17:38:10

demian
Member
From: Frankfurt, Germany
Registered: 2009-05-06
Posts: 709

Re: Script for Window tiling in openbox

Hey ans5685,

thank you for implementing the active_{left,right} options. They work perfectly. The iconify bug seems to have disappeared too.

i have to say, wmtiler is priceless. openbox with ondemand tiling is the exact right combination of floating and tiling window manager for me. Now, if only Openbox had some of the new functionality of the gnome-shell (workspace management (miniatures, dragging), screenedge actions, expose-like window-tabbing mode). A fella can dream, right?

But to answer your question regarding the swap feature:

ans5685 wrote:

Unless of course you want just the two of them to be swapped while leaving the others unaffected.

Yup, that's what i meant. I don't always have all my windows tiled and with floating windows it's sometimes very useful to be able to swap just two windows and ignoring any of the others.

That's it, I'm out of suggestions for now. If I stumble upon any other bugs I'll let you know. Thanks for sharing this script though, seriously.

Regards,
demian

Last edited by demian (2011-05-16 17:42:09)


no place like /home
github

Offline

#11 2011-05-17 17:01:59

tacticalbread
Member
From: Bay Area, CA
Registered: 2011-04-09
Posts: 127
Website

Re: Script for Window tiling in openbox

I wrote something quite similar to this a few weeks ago in zsh, but I didn't implement any sort of layout; I took influence from Subtle WM, and the manual tiling approach. I didn't share it, as I got bored of it, before I deemed it usable, but feel free to check it out. https://github.com/tacticalbread/shtile

It's sort of written in zsh, but I'm pretty sure the only non bash combatible thing is the decimal division. (bash only supports integer math).


don't save us from the flames

Offline

#12 2012-09-04 13:13:38

xinit
Member
Registered: 2011-11-12
Posts: 23

Re: Script for Window tiling in openbox

very nice on demand tiling smile

works very fine for me, thanks for sharing.

You have made any changes, improvements?

Offline

#13 2012-09-04 14:29:52

stryder
Member
Registered: 2009-02-28
Posts: 500

Re: Script for Window tiling in openbox

Didn't know this existed. I'm finding it useful too. Thanks.

Offline

Board footer

Powered by FluxBB