This forum has been archived. All content is frozen. Please use KDE Discuss instead.

KWin Desktop Effect / setup similar to Compiz plugin Grid?

Tags: None
(comma "," separated)
User avatar
Anpu
Registered Member
Posts
9
Karma
0
OS
Hi, as title says, I would like to configure KWin's shortcuts for windows moving / tiling to work just like Compiz's Grid plugin.

Example how Grid does it: http://www.youtube.com/watch?v=cHMKhiZmlV0
Keyboard shortcuts config screenshot: http://www.dodaj.rs/?1m/13m/3sd5T2nr/example.png

On the video, user first moves it to top left, then to top (resizing it from left screen edge to right), then top right, bottom right, bottom left, left, right, and then presses shortcuts for right two more times which resized window twice, then presses centre combo, right, top right, bottom right for terminal and left for Firefox.

So, what I would like to achieve in KDE is to be able to arrange opened windows like Grid allows. The reason behind it is because developers in company I work in have a lot of windows open during development, and Grid allowed them to quickly position them on the screen for the best view on all. We recently moved from Ubuntu 11.04 to Kubuntu 12.04 because we found that KDE really improves developer's efficiency (kudos to Kate and Dolphin especially).

What I tried was Global configuration for KWin shortcuts, "Quick Tile Window to the Bottom / Top Left / Right and Pack Window Up / Down, but it wasn't that good. Additionally, some positions required to press shortcuts twice to react. And also there is a bug in Numpad on KDE since 4.2 that doesn't allow setting up numpad buttons as shortcuts (but thats a problem I can live with until its fixed).

Is there a better KWin shortcut combination, some feature or plugin / package I m missing, that might be a solution (or close enough one) to what I am trying to achieve?

Thanks!
User avatar
toad
Global Moderator
Posts
1258
Karma
7
OS
afaik kwin is already capable of arranging up to four windows elegantly and quickly.

If I want to have only two windows, one half top and the other half bottom, I pull them into their respective corners (so that they occupy a quarter of the screen) and right click on the maximise button. Not the most elegant solution perhaps but it works.

Other than that the only feature kwin does not have is the setting where a window occupies a third of the screen...


Debian testing
User avatar
Anpu
Registered Member
Posts
9
Karma
0
OS
toad wrote:afaik kwin is already capable of arranging up to four windows elegantly and quickly.

If I want to have only two windows, one half top and the other half bottom, I pull them into their respective corners (so that they occupy a quarter of the screen) and right click on the maximise button. Not the most elegant solution perhaps but it works.

Other than that the only feature kwin does not have is the setting where a window occupies a third of the screen...

Hi, thanks.
Yes I know that you can drag window to the edge of the screen to resize window to quater or half. But what I am looking for is to do it via keyboard because:
1. it is way faster to just press key than drag all windows around to hit the particular edge
2. It is not so comfortable to do this when you have two monitors (which all developers have) because there is a "margin" between two monitors, and often you will just accidentally move window slightly off the left screen into a right screen.

I hope you get my point.
Minio
Registered Member
Posts
177
Karma
1
OS
You want to enable tiling in Kwin options.

But please note that KWin tiling capabilities are quite limited. As far as I remember reading KDE Planet, this feature will be removed in future versions of KWin (as main developer thinks that tiling can be much better achieved with KWin script; I have no idea if he intends to write such a script and provide it by default).

In the meanwhile you might have more luck scripting wmctrl and assigning scripts to different keyboard shortcuts.


Best regards
Mirosław Zalewski
luebking
Karma
0
"kcmshell4 keys", select kwin, filter for quick tiling.
You might also be interested in the packing shortcus.
User avatar
toad
Global Moderator
Posts
1258
Karma
7
OS
Also, perhaps you could stitch something together using xbindkeys and qdbusviewer...


Debian testing
User avatar
Anpu
Registered Member
Posts
9
Karma
0
OS
luebking wrote:"kcmshell4 keys", select kwin, filter for quick tiling.
You might also be interested in the packing shortcus.

As I said previously, I used combination of "Quick Tile Window to the xxx" shortcuts but it doesnt completely do what I d like to, and also for some reason reacted only when pressing shortcuts twice.

@Minio: if I remember right, I think I saw in KDE 4.9 option to load a script, but we still here run 4.8.5 (as those are company computers, I ve yet to get an approval for 4.9.x upgrade). Nice idea with wmctrl. I didnt know for it, and took a quick look: it can move and resize windows, so it looks promising!

Edit: any resources / tutorials regarding making such KWin scripts? Just to look at in case we upgrade to KDE 4.9.x

@toad: hm that "sounds" a bit more hard for me, probably due to my inexperience in that field. Any recomended references / starting points / links that might be handy for such an adventure?

Thanks a lot, people!
Minio
Registered Member
Posts
177
Karma
1
OS
Anpu wrote:Edit: any resources / tutorials regarding making such KWin scripts? Just to look at in case we upgrade to KDE 4.9.x

http://techbase.kde.org/Development/Tut ... /Scripting

KWin 4.8 can do scripts as well, but it's capabilities are limited.


Best regards
Mirosław Zalewski
luebking
Karma
0
Anpu wrote:
luebking wrote:"kcmshell4 keys", select kwin, filter for quick tiling.
You might also be interested in the packing shortcus.

As I said previously, I used combination of "Quick Tile Window to the xxx" shortcuts but it doesnt completely do what I d like to, and also for some reason reacted only when pressing shortcuts twice.


Actually you said and I kindly replied to
Anpu wrote:Yes I know that you can drag window to the edge of the screen to resize window to quater or half. But what I am looking for is to do it via keyboard


And the packing shortcuts are most likely what you're looking for beyond this, since they allow you to move the windows around until hitting another windows and also grow/shrink by this.
User avatar
Anpu
Registered Member
Posts
9
Karma
0
OS
Ok, so until we move to KDE 4.9, I made a Bash script based on wmctrl. It is designed to work like Grid plugin (currently lacking only window shrinking on double press), and should be good to use in single and dual monitor (even if monitors have different resolutions). It also means that script will check for window position, compare with resolutions and decide if window is on left or right monitor, and then apply wmctrl to the required position.

The only "downside" is GAP_TOP and GAP_BOTTOM variables in the script which is actually my top and bottom Plasma panel. I don't know how to detect if there is a panel present on the desktop via Bash, so in case you have ideas throw them in!

All kind of suggestions, patches, improvements and comments are very welcome! I know its not the perfect and polished (especially that "fixed" plasma part...). To use this, you need to install wmctrl, naturally. :)

Now, because of KDE bug with Numpad (very old one!) I set it on y,u,i,h,j,k,n,m and , . For each shortcut I call a script with one argument which tells to script where window should go:
Image

So for mode "RIGHT" (to tile window right) I call script with -r argument, etc.

Finally, here is a code:
Code: Select all
#!/bin/bash

# number of monitors
MONITORS=`xrandr | grep -w connected | wc -l`

# make a gap because of top panel
GAP_TOP=25
GAP_BOTTOM=45

#find x position of active window
GET_X_POS=`xdpyinfo | grep focus | grep -E -o 0x[0-9a-f]+`
X_POS=`xwininfo -id $GET_X_POS | grep -w "Absolute upper-left X:" | awk '{print $4}'`


if [ "$MONITORS" -eq "2" ]; then
  #monitor 1 X size and Y size
  X_RES1=`xrandr | grep "*+" | awk '{print $1}' | cut -d'x' -f 1 | sed -n 1p`
  Y_RES1=`xrandr | grep "*+" | awk '{print $1}' | cut -d'x' -f 2 | sed -n 1p`

  #monitor 2 X size and Y size
  X_RES2=`xrandr | grep "*+" | awk '{print $1}' | cut -d'x' -f 1 | sed -n 2p`
  Y_RES2=`xrandr | grep "*+" | awk '{print $1}' | cut -d'x' -f 2 | sed -n 2p`

  #desktop width
  WIDTH=$(($X_RES1+$X_RES2))
 
#   if [ "$Y_RES1" -ge "$Y_RES2" ]; then
#     HEIGHT=$Y_RES1
#   else
#     HEIGHT=$Y_RES2
#   fi
else
  X_RES=`xrandr | grep "*+" | awk '{print $1}' | cut -d'x' -f 1 | sed -n 1p`
  Y_RES=`xrandr | grep "*+" | awk '{print $1}' | cut -d'x' -f 2 | sed -n 1p`
 
  #desktop width
  WIDTH=$X_RES
 
  #desktop height
  HEIGHT=$Y_RES
fi

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

#see what the user wants to do
case $1 in
  "-l")
    MODE="LEFT"
    ;;       
  "-r")
    MODE="RIGHT"
    ;;       
  "-t")
    MODE="TOP"
    ;;       
  "-b")
    MODE="BOTTOM"
    ;;       
  "-y")
    MODE="TOP_LEFT"
    ;;       
  "-i")
    MODE="TOP_RIGHT"
    ;;
  "-n")
    MODE="BOTTOM_LEFT"
    ;;   
  "-m")
    MODE="BOTTOM_RIGHT"
    ;;       
  "-c")
    MODE="CENTER"
    ;;   
  *) 
    MODE="LEFT"
    ;;
esac

case $MODE in
  "LEFT")
    if [ "$MONITORS"  == "2" ]; then
      # left monitor
      if [ "$X_POS" -lt "$X_RES1" ]; then
        X=$(($X_RES1/2))
        Y=$(($Y_RES1-$GAP_BOTTOM-$GAP_TOP))
        wmctrl -r :ACTIVE: -e "1,0,$GAP_TOP,$X,$Y"
      #right monitor
      else
        X=$(($X_RES2/2))
        Y=$(($Y_RES2-$GAP_BOTTOM-$GAP_TOP))
        wmctrl -r :ACTIVE: -e "1,$X_RES1,$GAP_TOP,$X,$Y"
      fi
    else
      X=$(($WIDTH/2))
      Y=$(($HEIGHT-$GAP_BOTTOM-$GAP_TOP))
      wmctrl -r :ACTIVE: -e "1,0,$GAP_TOP,$X,$Y"
    fi
    ;;
  "RIGHT")
    if [ "$MONITORS"  == "2" ]; then
      # left monitor
      if [ "$X_POS" -lt "$X_RES1" ]; then
        X=$(($X_RES1/2))
        Y=$(($Y_RES1-$GAP_BOTTOM-$GAP_TOP))
        wmctrl -r :ACTIVE: -e "1,$X,$GAP_TOP,$X,$Y"
        #right monitor
      else
        X=$(($X_RES2/2))
        Y=$(($Y_RES2-$GAP_BOTTOM-$GAP_TOP))
        wmctrl -r :ACTIVE: -e "1,$(($X+$X_RES1)),$GAP_TOP,$X,$Y"
      fi
    else
      X=$(($WIDTH/2))
      Y=$(($HEIGHT-$GAP_BOTTOM-$GAP_TOP))
      wmctrl -r :ACTIVE: -e "1,$X,$GAP_TOP,$X,$Y"
    fi
    ;;
  "TOP")
    if [ "$MONITORS"  == "2" ]; then
      # left monitor
      if [ "$X_POS" -lt "$X_RES1" ]; then
        X=$X_RES1
        Y=$(($Y_RES1/2))
        wmctrl -r :ACTIVE: -e "1,0,$GAP_TOP,$X,$(($Y-$GAP_BOTTOM-$GAP_TOP))"
        #right monitor
      else
        X=$X_RES2
        Y=$(($Y_RES2/2))
        wmctrl -r :ACTIVE: -e "1,$X,$GAP_TOP,$X,$Y"
      fi
    else
      X=$WIDTH
      Y=$(($HEIGHT/2-$GAP_BOTTOM-$GAP_TOP))
      wmctrl -r :ACTIVE: -e "1,0,$GAP_TOP,$X,$Y"
    fi
    ;;
  "BOTTOM")
    if [ "$MONITORS"  == "2" ]; then
      # left monitor
      if [ "$X_POS" -lt "$X_RES1" ]; then
        X=$X_RES1
        Y=$(($Y_RES1/2))
        wmctrl -r :ACTIVE: -e "1,0,$(($Y-$GAP_TOP)),$X,$(($Y-$GAP_BOTTOM))"
        #right monitor
      else
        X=$X_RES2
        Y=$(($Y_RES2/2))
        wmctrl -r :ACTIVE: -e "1,$X,$Y,$X,$(($Y-$GAP_BOTTOM))"
      fi
    else
      X=$WIDTH
      Y=$(($HEIGHT/2))
      wmctrl -r :ACTIVE: -e "1,0,$Y,$X,$(($Y-$GAP_BOTTOM))"
    fi
    ;;
  "TOP_LEFT")
    if [ "$MONITORS"  == "2" ]; then
      # left monitor
      if [ "$X_POS" -lt "$X_RES1" ]; then
        X=$(($X_RES1/2))
        Y=$(($Y_RES1/2))
        wmctrl -r :ACTIVE: -e "1,0,$GAP_TOP,$X,$Y"
        #right monitor
      else
        X=$X_RES1
        Y=$(($Y_RES2/2))
        wmctrl -r :ACTIVE: -e "1,$X,$GAP_BOTTOM,$(($X_RES2/2)),$Y"
      fi
    else
      X=$(($WIDTH/2))
      Y=$(($HEIGHT/2))
      wmctrl -r :ACTIVE: -e "1,0,$GAP_TOP,$X,$Y"
    fi
    ;;
  "TOP_RIGHT")
    if [ "$MONITORS"  == "2" ]; then
      # left monitor
      if [ "$X_POS" -lt "$X_RES1" ]; then
        X=$(($X_RES1/2))
        Y=$(($Y_RES1/2))
        wmctrl -r :ACTIVE: -e "1,$X,$GAP_TOP,$X,$Y"
      #right monitor
      else
        X=$X_RES1
        Y=$(($Y_RES2/2))
        wmctrl -r :ACTIVE: -e "1,$(($X+($X_RES2/2))),$GAP_TOP,$(($X_RES2/2)),$Y"
      fi
    else
      X=$((2))
      Y=$(($HEIGHT/2))
      wmctrl -r :ACTIVE: -e "1,$X,$GAP_TOP,$X,$Y"
    fi
    ;;
  "BOTTOM_LEFT")
    if [ "$MONITORS"  == "2" ]; then
      # left monitor
      if [ "$X_POS" -lt "$X_RES1" ]; then
        X=$(($X_RES1/2))
        Y=$(($Y_RES1/2))
        wmctrl -r :ACTIVE: -e "1,0,$(($Y-$GAP_BOTTOM-$GAP_TOP)),$X,$Y"
      #right monitor
      else
        X=$X_RES1
        Y=$(($Y_RES2/2))
        wmctrl -r :ACTIVE: -e "1,$X,$(($Y-$GAP_BOTTOM-$GAP_TOP)),$(($X_RES2/2)),$Y"
      fi
    else
      X=$(($WIDTH/2))
      Y=$(($HEIGHT/2))
      wmctrl -r :ACTIVE: -e "1,0,$(($Y-$GAP_BOTTOM)),$X,$Y"
    fi
    ;;
  "BOTTOM_RIGHT")
    if [ "$MONITORS"  == "2" ]; then
      # left monitor
      if [ "$X_POS" -lt "$X_RES1" ]; then
        X=$(($X_RES1/2))
        Y=$(($Y_RES1/2))
        wmctrl -r :ACTIVE: -e "1,$X,$(($Y-$GAP_BOTTOM-$GAP_TOP)),$X,$Y"
      #right monitor
      else
        X=$(($X_RES1+($X_RES2/2)))
        Y=$(($Y_RES2/2))
        wmctrl -r :ACTIVE: -e "1,$X,$(($Y-$GAP_BOTTOM-$GAP_TOP)),$(($X_RES2/2)),$Y"
      fi
    else
      X=$(($WIDTH/2))
      Y=$(($HEIGHT/2))
      wmctrl -r :ACTIVE: -e "1,$X,$(($Y-$GAP_BOTTOM)),$X,$Y"
    fi
    ;;
  "CENTER")
    if [ "$MONITORS"  == "2" ]; then
      # left monitor
      if [ "$X_POS" -lt "$X_RES1" ]; then
        X=$X_RES1
        Y=$Y_RES1
        wmctrl -r :ACTIVE: -e "1,0,$GAP_TOP,$X,$(($Y-$GAP_BOTTOM-$GAP_TOP))"
      #right monitor
      else
        X=$X_RES1
        Y=$Y_RES2
        wmctrl -r :ACTIVE: -e "1,$X,$GAP_TOP,$X_RES2,$(($Y-$GAP_BOTTOM-$GAP_TOP))"
      fi
    else
      X=$WIDTH
      Y=$(($HEIGHT-$GAP_BOTTOM-$GAP_TOP))
      wmctrl -r :ACTIVE: -e "1,0,$GAP_TOP,$X,$Y"
    fi
    ;;
esac
User avatar
Anpu
Registered Member
Posts
9
Karma
0
OS
Is there a way to actually get Plasma panels size and if they are set on autohide? It can be even some config file, it doesnt need to be some command if it doesnt exist. Then I can easy access with Bash to config file and extract such data.

I want to improve script so it detects present panels and adjust its calculations for window size dynamically without setiing it manually.
luebking
Karma
0
you'll have to obtain the values from the _NET_WM_STRUT properties on all (dock type) windows (try xprop)
User avatar
Anpu
Registered Member
Posts
9
Karma
0
OS
luebking wrote:you'll have to obtain the values from the _NET_WM_STRUT properties on all (dock type) windows (try xprop)

Thanks, that did a trick.
I made new version in Python: http://paste.opensuse.org/a78362d8
Works correctly for single or dual monitor setup.
The only problem: it doesnt work with non KDE windows / programs (Thunderbird, Terminator, FF, Chrome..)! It might be due to using KDE Global shortcuts for calling script for particular window. Needs a bit of an investigation...


Bookmarks



Who is online

Registered users: bartoloni, Bing [Bot], Evergrowing, Google [Bot], ourcraft