5

How should I go about moving a window created with PySide using the window manager?

I see that kdeui has the NETRootInfo class with a moveResizeRequest method, which does exactly what I want. The following:

from PySide.QtCore import Qt
from PyKDE4 import kdeui
from PySide.QtGui import QX11Info
import sys
from ctypes import CDLL
Xlib = CDLL('libX11.so.6')

def move_window(window, event):
    if event.buttons() & Qt.LeftButton:
        pos = event.buttonDownScreenPos(Qt.LeftButton)
        Xlib.XUngrabPointer(QX11Info.display(), QX11Info.appTime())
        rootinfo = kdeui.NETRootInfo(QX11Info.display(), kdeui.NET.WMMoveResize)
        rootinfo.moveResizeRequest(window.winId(), pos.x(), pos.y(), kdeui.NET.Move)

gives me:

TypeError: NETRootInfo(): arguments did not match any overloaded call:
  overload 1: argument 1 has unexpected type 'int'
  overload 2: argument 1 has unexpected type 'int'
  overload 3: argument 1 has unexpected type 'int'
  overload 4: argument 1 has unexpected type 'int'

This error is caused because QX11Info.display() returns a long (pointer), and not a Display structure.

I can use PyQt4's QX11Info.display() as the first parameter to NETRootInfo's constructor instead of the PySide one, like:

...
from PySide.QtGui import QX11Info
from PyQt4.QtGui import QX11Info as QX11InfoQt
...

def move_window(window, event):
    if event.buttons() & Qt.LeftButton:
        pos = event.buttonDownScreenPos(Qt.LeftButton)
        Xlib.XUngrabPointer(QX11Info.display(), QX11Info.appTime())
        rootinfo = kdeui.NETRootInfo(QX11InfoQt.display(), kdeui.NET.WMMoveResize)
        rootinfo.moveResizeRequest(window.winId(), pos.x(), pos.y(), kdeui.NET.Move)

But this adds a dependency on PyQt4 in addition to PySide.

Additionally, I have tried using Xlib's XMoveWindow function, but this prevents the window from dragging partially off screen, and does not give the move feedback (e.g. transparency effects) provided by window managers like Compiz or KWin.

My question is:

  1. How to I convert PySide's QX11Info.display() into a "Display" that can be passed to kdeui.NETRootInfo, or
  2. How do I use Python and Xlib (either with python-xlib or through libX11.so) to use a message like _NET_WM_MOVERESIZE in order to move the window?
D K
  • 5,530
  • 7
  • 31
  • 45
  • Surely PyKDE4 already requires PyQt4 - so there is no *additional* dependency for option (1). – ekhumoro Sep 28 '12 at 19:23
  • Not quite. PyKDE4 is a wrapper for KDE4. KDE4 requires Qt4 to operate, but not **Py** Qt4. The Python wrapper is purely a C++ wrapper, and therefore has no dependency on PyQt4. – D K Sep 28 '12 at 20:00
  • Nope. PyKDE is now maintained as part of KDE, but it has always required both PyQt and SIP and that has not changed: see [here](http://www.riverbankcomputing.com/software/pykde/intro) and [here](http://techbase.kde.org/Development/Languages/Python) for details. – ekhumoro Sep 28 '12 at 21:37
  • Ooh. I didn't realize that. Thank you for the links. Just wondering though, how is PyKDE4 LGPL if it requires PyQt4, which is GPL? – D K Sep 28 '12 at 22:32
  • Well, PyQt depends on Qt - which *was* GPL, but is now LGPL; and yet PyQt remains GPL. Basically, the author/owner of a project gets to decide on what licencing is used. PyKDE was also GPL for many years (when it was maintained by Phil Thompson, and then later by Jim Bublitz). But when KDE took over ownership of the project, they decided to switch to LGPL (quite naturally, since KDE is itself LGPL). – ekhumoro Sep 28 '12 at 23:59
  • why would you want to use `kdeui`when you can do with `QPropertyAnimation` !in `PySide`. Here is the link to pyside implementation http://qt-project.org/forums/viewthread/4927 – Ciasto piekarz Dec 26 '13 at 18:53
  • @san Thank you for the suggestion, but I do not see how `QPropertyAnimation`s have to do with moving a window with the window manager. – D K Dec 28 '13 at 02:39
  • I meant what is the reason or advantage of using window manager ? – Ciasto piekarz Dec 28 '13 at 04:38
  • 1
    That's a good question. By using the window manager to move the window, you are telling it (unsurprisingly) that the window is moving. This will trigger the various plugins/effects associated with moving a window. In compiz and kwin for example, a plugin may be enabled to reduce the opacity of the window when dragging it. Also, Windows-style snapping can be used with these WMs. By not using the WM, these features cannot work because the WM doesn't know if the window is being moved, or just relocated (a bunch of times). – D K Dec 28 '13 at 13:27

1 Answers1

0

I suspect your last call actually has different signature, perhaps like this:

moveResizeRequest(<window object>, <int>, <int>, <const>)

while you are trying to squeeze window id (int) instead.

having had a bit of experience with pygtk (and not pykde), you probably have to enumerate all high-level windows in given screen to get a window handle object.

Similarly, from c++ kde docs:

display     An X11 Display struct.
supportWindow   The Window id of the supportWindow. The supportWindow must be created by the window manager as a child of the rootWindow. The supportWindow must not be destroyed until the Window Manager exits.

while you are trying to squeeze some constant into supportWindow.

Dima Tisnek
  • 11,241
  • 4
  • 68
  • 120