SEARCH

Enter your search query in the box above ^, or use the forum search tool.

You are not logged in.

#1 2013-02-27 22:58:19

errorist
#! CrunchBanger
Registered: 2012-05-24
Posts: 100

Openbox: "Togglefloating"-script

Hello !

My problem, to (un)set the window-decos from inside a script, has fortunately
being solved. But I haven't found another way than a workaround with Xdotool
and the OB-action "ToggleDecorations".

When you see "togglefloating for OB", you might ask you: Why that, on a floating
WM ???

My intention for scripting toggle_floating was, to emulate this wellknown feature
of many tiling-wms for OBs manual tiling.

Its useful, when you want to work in a little window in the tiling layout, but
don't want to fullscreen it.

Technically it's just a move+resize action with preconfigured coordinates and sizes.
The old values are stored into a file when floating, from where they are getting
restored by unfloating the window.

And as a little gimmick, the script also restores the windows correctly when you
have changed its decos during floating.

To make sure, an empty storing file exists in the choosen dir at startup, there has
to be the following addition in the autostart file :

  ## toggle_floating - Makes sure, the dir ~/.config/openbox/data exists,
  ## and has a cleaned (empty) togglefloat - file inside.
  if [ ! -d ~/.config/openbox/data ]
    then
      mkdir ~/.config/openbox/data
      : > ~/.config/openbox/data/togglefloat
    else
      : > ~/.config/openbox/data/togglefloat
  fi &

And there I have a question : Does it matter at all if the "&" is inside the
if-construct or at the end ?

The script should be placed in the ~/.config/openbox/scripts dir, but can be placed
anywhere, as long as the paths in the toggle_floating- and the autostart-scripts
are customized.

And finally, to get it working, you must have defined a shortcut for the OB-action
"ToggleDecorations" in your OB-rc.xml and put it into the xdotool-line in the script.

Of course, you also need a shortcut for the togglefloat script, too, like this
excerpt from my rc.xml:

    <keybind key="W-Prior">
      <action name="Execute">
        <execute>
           ~/.config/openbox/scripts/toggle_floating.bash
        </execute>
      </action>
    </keybind>

Copy and paste this here, and don't forget to make it executable :

#!/bin/bash
#
# Titel           : toggle_floating.bash
# Version         : 0.8
# Description     : Toggle-flaoting action for Openbox, mainly useful in manual tiled
#                   workspace layouts.
# Requirements    : It needs a modern bash, and additionally Wmctrl, Xprop, Xdotool
#                   and of course Openbox on a Gnu/Linux-system.
#		      Add the few lines from the #!-thread to your autostart.sh.
# Miscellaneous   : There is not any license for this. Use it on your own risc, the author
#                   refuses any responsibility, and you will not get payed for using it !
#

# Current window-ID

hex_RohFensterID=$(xprop -root _NET_ACTIVE_WINDOW | awk '{ print $5 }')
hex_AktFensterID=${hex_RohFensterID/0[xX]/0x0}


# Deco-status

int_DekoStatus=$(xprop -id $hex_AktFensterID _NET_WM_STATE | gawk '{int_Wert = 1; for (j = 2; j <= NF; j++)\
              {if ( $j == "_OB_WM_STATE_UNDECORATED" ) {int_Wert = 0; break;}} {print int_Wert}}')


# Deco-offsets

aint_DekoOffset=($(xprop -id $hex_AktFensterID _NET_FRAME_EXTENTS | gawk '{print $3, $4, $5, $6}'))
int_DekoOffsetX=${aint_DekoOffset[0]}
int_DekoOffsetY=${aint_DekoOffset[2]}

# For redundancy and at the first run of the script, no new start required

if [ ! -d ~/.config/openbox/data/ ]
  then
    mkdir ~/.config/openbox/data/
    : > ~/.config/openbox/data/togglefloat
  else
    if [ ! -e ~/.config/openbox/data/togglefloat ]; then
      : > ~/.config/openbox/data/togglefloat
    fi
fi


# Reading the "togglefloat"-storagefile, than clearing it

aint_TF_Alt=($( gawk '{ print }' ~/.config/openbox/data/togglefloat ))

: > ~/.config/openbox/data/togglefloat


# Checking if current window is already listed

int_Aktiv=0                             # Current window is not listed

if [ ${#aint_TF_Alt[*]} -ge 9 ]; then   # File entries are existing
  for (( i = 0; i <= ${#aint_TF_Alt[*]} - 9; i += 9 ))
    do
      if [ ${aint_TF_Alt[$i]} = $hex_AktFensterID ]; then
        int_Aktiv=1                     # Current window is listed
        break
      fi
    done
fi


# Interpreting togglefloating-shortcut, floating /unfloating, eventually deco toggling
# +and writing other entries back

if [ ${#aint_TF_Alt[*]} -lt 9 -o $int_Aktiv -eq 0 ]                             # No entry or entries, but
  then                                                                          # +current window is not listed
    aint_TF_Neu=($(wmctrl -lG | gawk -v AktFensterID="$hex_AktFensterID"\
              -v DekoStatus=$int_DekoStatus -v DekoOffsetX=$int_DekoOffsetX -v DekoOffsetY=$int_DekoOffsetY\
              '{if ( $1 == AktFensterID ) print $1, $2, $3, $4, $5, $6, DekoStatus, +DekoOffsetX, +DekoOffsetY}'))
    wmctrl -i -r $hex_AktFensterID -e 10,100,90,824,600                         # floating current window
    echo ${aint_TF_Neu[*]} >> ~/.config/openbox/data/togglefloat                # listing current window
fi

for (( i = 0; i <= ${#aint_TF_Alt[*]} - 9; i += 9 ))
  do
    if [ ${aint_TF_Alt[$i]} = $hex_AktFensterID ]               # Current window already floatet ?
      then                                                      # +than unfloating it
        if [ $int_DekoStatus -ne ${aint_TF_Alt[$i+6]} ]         # Deco changed during floating ?
          then                                                  # +than toggling deco
            (( int_X = ${aint_TF_Alt[$i+2]} - ${aint_TF_Alt[$i+7]}*2 ))
            (( int_Y = ${aint_TF_Alt[$i+3]} - ${aint_TF_Alt[$i+8]}*2 ))
            wmctrl -i -r $hex_AktFensterID -e 10,$int_X,$int_Y,${aint_TF_Alt[$i+4]},${aint_TF_Alt[$i+5]} # Unfloating current window
            xdotool key super+Insert                            # Put in here your shortcut for "ToggleDecorations"
          else
            (( int_X = ${aint_TF_Alt[$i+2]} - ${aint_TF_Alt[$i+7]} ))
            (( int_Y = ${aint_TF_Alt[$i+3]} - ${aint_TF_Alt[$i+8]} ))
            wmctrl -i -r $hex_AktFensterID -e 10,$int_X,$int_Y,${aint_TF_Alt[$i+4]},${aint_TF_Alt[$i+5]} # Unfloating current window
        fi
      else
        aint_wmctrl=""
        for (( j = 0; j <= 8; j++ ))                            # Writing back the other old entries, if existing
          do
            aint_wmctrl[$j]=${aint_TF_Alt[$i+j]}
          done
        echo ${aint_wmctrl[*]} >> ~/.config/openbox/data/togglefloat
    fi
  done

exit 0

I hope, it will work on your systems, too, and maybe, it will enhance your OB manual tiling experiences...


Cheers !

errorist

Edit: Dir corrected

Last edited by errorist (2013-02-28 08:10:14)

Offline

Help fund CrunchBang, donate to the project!

#2 2013-02-28 10:19:39

xaos52
The Good Doctor
From: Planet of the @s
Registered: 2011-06-24
Posts: 4,602

Re: Openbox: "Togglefloating"-script

Hi errorist,

No need to use the & in this case because the command returns immediately.
The & is only necessary for starting processes that remain running in the background.

I haven't ran the script - not running tiled WM's any more. I reverted to good old OB - just skimmed it quickly and it looks OK.

BTW the addition to autostart is not really necessary, since you create the data in the script if it does not exist. I would recommend using a temp file for 'togglefloat' that you remove when the script finishes.
Something like

togglefloat=$(mktemp /tmp/togglefloat.XXXXXX)

or

togglefloat=$(mktemp ~/tmp/togglefloat.XXXXXX)

to create it.

Use

$togglefloat

to write to it.

and

rm $togglefloat

to clean it up.

Maybe it would also be a good idea to trap any signals and clean up the temp file when something goes wrong in your script, or when it is sent the BREAK command.

Nice script.

cheers

Last edited by xaos52 (2013-02-28 10:39:28)

Offline

#3 2013-02-28 15:22:50

errorist
#! CrunchBanger
Registered: 2012-05-24
Posts: 100

Re: Openbox: "Togglefloating"-script

@ xaos52 : Ahh, and I wondered last time, why it had run without problems, had've
forgotten the "&" at all.
Now that is clear for me, thanks.

xaos52 wrote:

- not running tiled WM's any more. I reverted to good old OB -

You are quite right here !

OB, with its move/grow/shrink - to actions is capable enough, IMO, for basic tiling.
On my different workspaces I'm always using different styles, some for fullscreen,
others for floating, but also some for tiled layouts.
There is really no need for any tiling-emulators or the use of a special tiler
( though there are some I really love ! ), but a little enhancement here and there
can be useful for OBs manual tiling.

The script is a mess, I know !
But it was not really designed from the beginning. I thought, I could use it for
testing some new ideas, "Just" moving and resizing windows from one place to
annother, and back again...

Had to discover, how the deco-withs are used, in relation to a special gravity.
I don't tried it, but the script may only places the windows correcty with gravity
north-west, which seems to be default. For other gravities it can easily be modified.

Every time I'm looking newly over the script, I'm thinking at once, the
autostart-addition is needless, but it is not.

The script is run twice, when you have floated and unfloated.
But it can only check, in which run it is and for which window, if it can read the data
of the previous run.

The creation of the data-file in the autostart.sh is only for making shure, the
file is really empty at startup.
At the script-start, it is left untouched, if existing.

And that leads to the error-handling, which I don't have at all.
This script here is harmless, the worse thing it can do, is misplacing the windows.
Lasy as I am, I'm looking, if it works, beeing the errorhandler errorist myself...
If something is wrong, just deleting the data-file does it.

But there may be other situations, where trapping is a must...
I hope, my paranoia overtops my lazyness, when it becomes critical !

Thanks for your suggestions, nevertheless !


Cheers !

errorist

Last edited by errorist (2013-02-28 15:27:24)

Offline

#4 2013-03-12 15:13:20

errorist
#! CrunchBanger
Registered: 2012-05-24
Posts: 100

Re: Openbox: "Togglefloating"-script

Hello !

After some bughunting, a few code-corrections and adding a new feature, it is time
for toggle_floating.bash v0.9.

The new feature allows to use several shortcuts for different floating sizes (default
is 3).
Which size to use, the script gets from its parameters(optional,0-2 default).
When a window is floated with a specific shortcut, it can be unfloated with
any of the shortcuts.

@ xaos52 : Oohh, you did so well, pointing me to the missing error handling !
The longer I'm probing and looking through the script, the more bugs are appearing.
Annoying enough the obvious ones, the spooky errors are even worse...
And unfortunately, there are no error-handlers with repair functionality.

Here the new version:

#!/bin/bash
#===================================================================================================
#                                                                                                  #
# Titel           : toggle_floating.bash                                                           #
#                                                                                                  #
# Version         : 0.9                                                                            #
#                                                                                                  #
# Parameter       : 0 = Default, middle sized floating-window                                      #
#                   1 = Small floating-window                                                      #
#                   2 = Large floating-window                                                      #
#                                                                                                  #
# Execution       : toggle_floating.bash 0[1,2]                                                    #
#                                                                                                  #
# Description     : Toggle-floating action for Openbox, mainly useful in manual tiled              #
#                   workspace layouts.                                                             #
#                                                                                                  #
# Requirements    : It needs a modern bash, and additionally Wmctrl, Xprop, Xdotool                #
#                   and of course Openbox on a Gnu/Linux-system.                                   #
#                   Add the few lines from the #!-thread to your autostart.sh., they will          #
#                   prevent using false data from the former session.                              #
#                   You need a shortcut for OBs "ToggleDecorations" in your rc.xml, and            #
#                   have to add one(up to 3) for "toggle_floating.bash 0[1,2]", too.               #
#                                                                                                  #
# New Features    : Deco can be changed during floating and gets restored automatically            #
#                   on unfloating [v0.8].                                                          #
#                   Three floating-sizes available through command-line parameters. Unfloating     #
#                   works with any of the togglefloat-shortcuts, independently from the            #
#                   used one for floating [v0.9].                                                  #
#                                                                                                  #
# Changes         : Now checks, if there are enough array-members for a data-set, and if           #
#                   the old windowIDs are still present[01]. If not so, their dataset will         #
#                   be skipped.                                                                    #
#                   Adding extra counter for working-array[02].                                    #
#                   The comments are reworked a little, to make some of the chaos more             #
#                   readable, or readable at all.                                                  #
#                                                                                                  #
# Bugs          01: [Fixed] No test, if old listed windowIDs are actually existing.                #
#               02: [Fixed] Produces sparse working-array, when old listed windowIDs are skipped.  #
#               03: [Open]  Confuses OB somehow. After floating/unfloating a window, OBs maximize- #
#                           and deco-toggling don't restore the window correctly. But like above,  #
#                           plus changed deco, it behaves normal.                                  #
#                                                                                                  #
# Miscellaneous   : There is not any license for this. Use it on your own risc, the author         #
#                   refuses any responsibility, and you will not get payed for using it !          #
#                                                                                                  #
#==================================================================================================#


# +––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+
# | Current window-ID                                                                              |
# +––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+

hex_RohFensterID=$(xprop -root _NET_ACTIVE_WINDOW | awk '{ print $5 }')
hex_AktFensterID=${hex_RohFensterID/0[xX]/0x0}


# +––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+
# | Deco-status                                                                                    |
# +––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+

int_DekoStatus=$(xprop -id $hex_AktFensterID _NET_WM_STATE | gawk '{int_Wert = 1; for (j = 2; j <= NF; j++)\
              {if ( $j == "_OB_WM_STATE_UNDECORATED" ) {int_Wert = 0; break;}} {print int_Wert}}')

# +––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+
# | Deco-offsets                                                                                   |
# +––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+

aint_DekoOffset=($(xprop -id $hex_AktFensterID _NET_FRAME_EXTENTS | gawk '{print $3, $4, $5, $6}'))
int_DekoOffsetX=${aint_DekoOffset[0]}
int_DekoOffsetY=${aint_DekoOffset[2]}


# +––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+
# | Floating - Data (X, Y, width, height), 3 different placements and sizes for 3 shortcuts.       |
# +––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+

astr_XYWH=( 128,96,768,576 256,192,512,384 40,64,944,660 )      # Can be modified and extended.


# +––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+
# | For redundancy and at the first run of the script, no new start/OB-refresh required.           |
# +––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+

if [ ! -d ~/.config/openbox/data/ ]
  then
    mkdir ~/.config/openbox/data/
    : > ~/.config/openbox/data/togglefloat
  else
    if [ ! -e ~/.config/openbox/data/togglefloat ]; then
      : > ~/.config/openbox/data/togglefloat
    fi
fi


# +––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+
# | Reading the "togglefloat"-storagefile, than clearing it. Reading the current windows IDs.      |
# +––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+

aint_TF_Temp=($( gawk '{ print }' ~/.config/openbox/data/togglefloat ))
aint_TF_Ref_FID=($(wmctrl -l | gawk '{print $1}'))

: > ~/.config/openbox/data/togglefloat


# +––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+
# | Checking, if listed windows still are existing, if active window is already floated,           |
# | and that there are enough array-members for every data-set.                                    |
# +––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+

aint_TF_Alt=""                                    # "Array" empty
int_Aktiv=0                                       # Current window is not listed
int_Anz_DataSets=$(( ${#aint_TF_Temp[*]} / 9 ))   # Number of saved data-sets

if [ $int_Anz_DataSets -gt 0 ]; then                                   # At least one old data-set ?
  int_Adr_TF_Alt=0                                                     # Adress for the data-set in the working-array.
  for (( i = 0; i < int_Anz_DataSets * 9; i += 9 ))
    do
      for (( j = 0; j < ${#aint_TF_Ref_FID[*]}; j++ ))                 # Loop the current windowIDs.
        do
          if [ ${aint_TF_Ref_FID[j]} = ${aint_TF_Temp[i]} ]; then      # Listed window still existing ?
            for (( k = 0; k <= 8; k++ ))
              do
                aint_TF_Alt[$int_Adr_TF_Alt+$k]=${aint_TF_Temp[i+k]}   # Copying data-set into working-array.
              done
            (( int_Adr_TF_Alt += 9 ))                                  # Adress for the next data-set in working-array.
            if [ ${aint_TF_Temp[i]} = $hex_AktFensterID ]; then        # Active window listed (already floated) ?
              int_Aktiv=1                                              #+so we have to unfloat !
            fi
            break                                                      # Cancelling the rest of the for-loop in the
          fi                                                           #+current windowID array.
        done
    done
fi


# +––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+
# | Interpreting togglefloating-shortcut, floating /unfloating, eventually deco toggling           |
# | and writing other data-sets back.                                                              |
# +––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+

int_Anz_DataSets=$(( ${#aint_TF_Alt[*]} / 9 ))                                  # Number of saved data-sets left.

if [ $int_Anz_DataSets -eq 0 -o $int_Aktiv -eq 0 ]                              # No entry, or entries, but
  then                                                                          #+current window is not listed.
    aint_TF_Neu=($(wmctrl -lG | gawk -v AktFensterID="$hex_AktFensterID"\
              -v DekoStatus=$int_DekoStatus -v DekoOffsetX=$int_DekoOffsetX\
              -v DekoOffsetY=$int_DekoOffsetY '{if ( $1 == AktFensterID )\
              print $1, $2, $3, $4, $5, $6, DekoStatus, +DekoOffsetX, +DekoOffsetY}')) # Building new dataset here.

    wmctrl -i -r $hex_AktFensterID -e 10,${astr_XYWH[${1:-0}]}                  # Floating current window( size 0,1,2).
    echo ${aint_TF_Neu[*]} >> ~/.config/openbox/data/togglefloat                # Listing current window( writing
fi                                                                              #+new data-set into storage-file ).


if [ $int_Anz_DataSets -gt 0 ]; then                              # At least one old data-set stored ?
  for (( i = 0; i < int_Anz_DataSets * 9; i += 9 ))
    do
      if [ ${aint_TF_Alt[i]} = $hex_AktFensterID ]                # Active window already floatet ?
        then                                                      #+then unfloating it.
          if [ $int_DekoStatus -ne ${aint_TF_Alt[i+6]} ]          # Deco changed during floating ?
            then                                                  #+then toggling deco.
              (( int_X = ${aint_TF_Alt[i+2]} - ${aint_TF_Alt[i+7]}*2 ))
              (( int_Y = ${aint_TF_Alt[i+3]} - ${aint_TF_Alt[i+8]}*2 ))
              int_W=${aint_TF_Alt[i+4]}
              int_H=${aint_TF_Alt[i+5]}
                                                                  # Unfloating the current window.

              wmctrl -i -r $hex_AktFensterID -e 10,$int_X,$int_Y,$int_W,$int_H

              sleep 0.3                                           # Toggling deco back to original state.
              xdotool key super+Insert                            # Put in here your shortcut for "ToggleDecorations"
            else
              (( int_X = ${aint_TF_Alt[i+2]} - ${aint_TF_Alt[i+7]} ))
              (( int_Y = ${aint_TF_Alt[i+3]} - ${aint_TF_Alt[i+8]} ))
              int_W=${aint_TF_Alt[i+4]}
              int_H=${aint_TF_Alt[i+5]}
                                                                  # Unfloating the current window.

              wmctrl -i -r $hex_AktFensterID -e 10,$int_X,$int_Y,$int_W,$int_H
              sleep 0.3
          fi
        else
          aint_DataSet=""                                         # Current data-set not matching active window,
          for (( j = 0; j <= 8; j++ ))                            #+so writing it back into storage-file.
            do
              aint_DataSet[$j]=${aint_TF_Alt[i+j]}
            done
          echo ${aint_DataSet[*]} >> ~/.config/openbox/data/togglefloat
      fi
    done
fi

exit 0

And here again the autostart-addon:

  ## toggle_floating - Makes sure, the dir ~/.config/openbox/data exists,
  ## and has a cleaned (empty) togglefloat - file inside.
  if [ ! -d ~/.config/openbox/data ]
    then
      mkdir ~/.config/openbox/data
      : > ~/.config/openbox/data/togglefloat
    else
      : > ~/.config/openbox/data/togglefloat
  fi &

Hope, I'll manage to release the next time.


Cheers !

errorist

Last edited by errorist (2013-03-12 17:59:38)

Offline

Board footer

Powered by FluxBB

Copyright © 2012 CrunchBang Linux.
Proudly powered by Debian. Hosted by Linode.
Debian is a registered trademark of Software in the Public Interest, Inc.

Debian Logo