parkouss / pyewmh Goto Github PK
View Code? Open in Web Editor NEWAn implementation of EWMH (Extended Window Manager Hints) for python, based on Xlib.
License: GNU Lesser General Public License v3.0
An implementation of EWMH (Extended Window Manager Hints) for python, based on Xlib.
License: GNU Lesser General Public License v3.0
I would like to rename a window, but I can't. This is an example with getActiveWindow().
#!/usr/bin/python
from ewmh import EWMH
ewmh = EWMH()
# get the active window
win = ewmh.getActiveWindow()
title = "newtitle"
print 'data length:', len(title)
# set the name
ewmh.setWmName(win, title)
# flush request
ewmh.display.flush()
Logs:
<class 'Xlib.protocol.request.QueryExtension'>
data length: 8
Traceback (most recent call last):
File "test_2.py", line 15, in <module>
ewmh.setWmName(win, title)
File "/usr/local/lib/python2.7/dist-packages/ewmh/ewmh.py", line 136, in setWmName
self._setProperty('_NET_WM_NAME', name, win)
File "/usr/local/lib/python2.7/dist-packages/ewmh/ewmh.py", line 321, in _setProperty
ev = protocol.event.ClientMessage(window=win, client_type=self.display.get_atom(_type), data=(dataSize, data))
File "/usr/lib/python2.7/dist-packages/Xlib/protocol/rq.py", line 1531, in __init__
self._binary = self._fields.to_binary(*(), **keys)
File "/usr/lib/python2.7/dist-packages/Xlib/protocol/rq.py", line 1138, in to_binary
return self.to_binary(*varargs, **keys)
File "<string>", line 2, in to_binary
File "/usr/lib/python2.7/dist-packages/Xlib/protocol/rq.py", line 704, in pack_value
% (value, ))
Xlib.protocol.rq.BadDataError: Wrong data length for FixedPropertyData: (8, 'newtitle')
If I run this:
from ewmh import EWMH
ewmh = EWMH()
windows = ewmh.getClientList()
for w in windows:
# Window name (Title)
print(w.get_wm_name())
print(w.get_wm_class()[1])
I get:
Chromium
Google-chrome
Terminal
Xfce4-terminal
~/gits/test_ewmh/test.py (i3close) - Sublime Text
Sublime_text
While running:
xprop | grep WM_NAME
Outputs:
WM_NAME(UTF8_STRING) = "New Issue · parkouss/pyewmh - Chromium"
_NET_WM_NAME(UTF8_STRING) = "New Issue · parkouss/pyewmh - Chromium"
and
WM_NAME(UTF8_STRING) = "duckduckgo at DuckDuckGo - Google Chrome"
_NET_WM_NAME(UTF8_STRING) = "duckduckgo at DuckDuckGo - Google Chrome"
I have tested this on a new pypenv with ewmh-0.1.6, python-xlib-0.23, six-1.11.0 and Python 3.6.5
I can't test this on others environments or browsers right now, but maybe I'm doing something wrong.
Did you have any idea or want more info?
[This report was sent to me by someone without access to GitHub.]
There's a bunch of definitions like this one inside of ewmh/ewmh.py
:
def getWmState(self, win, str=False):
"""Get the list of states of the given window (property _NET_WM_STATE).
:param win: the window object
:param str: True to get a list of string states instead of int
:return: list of (int|str)"""
states = self._getProperty('_NET_WM_STATE', win)
if not str: return states
return map(self._getAtomName, states)
The map(self._getAtomName, states) part fails when states is None. None is returned when no state is set.
Possible fixes: Either change _getProperty
to return an empty Array when no properties are set or change that part, former seems more elegant to me.
I have some problems with DesktoGeometry and WorkArea values: I am trying to get the active window and resize it to fill the entire screen but when I use the function setMoveResizeWindow
with the WorkArea values it put the window in a different position.
This is my code:
from ewmh import EWMH
ewmh = EWMH()
# get desktop geometry and workarea
w, h = ewmh.getDesktopGeometry()
xr, yr, wr, hr = ewmh.getWorkArea()[:4]
print("Desktop Geometry: ", w, h)
print("Desktop WorkArea:", xr, yr, wr, hr)
# get active window
win = ewmh.getActiveWindow()
# resize window
ewmh.setMoveResizeWindow(
win,
x=xr,
y=yr,
w=wr,
h=hr
)
ewmh.display.flush()
I've tested this script on my ArchLinux + XFCE system and on a Ubuntu 20.4 WM, same problem but in different ways:
MWE:
import PySimpleGUI
import pywinctl
PySimpleGUI.popup('just say it!',
no_titlebar = False,
keep_on_top = True,
title = "dummy title",
non_blocking = True,
)
pywinctl.getAllAppsWindowsTitles()
Resulting error:
$ /bin/python3 /home/omlins/tmpwdir/juliadev/JustSayIt/src/gui_test2.py
Traceback (most recent call last):
File "/home/omlins/tmpwdir/juliadev/JustSayIt/src/gui_test2.py", line 11, in <module>
pywinctl.getAllAppsWindowsTitles()
File "/home/omlins/.local/lib/python3.10/site-packages/pywinctl/_pywinctl_linux.py", line 235, in getAllAppsWindowsTitles
appName = win.getAppName()
File "/home/omlins/.local/lib/python3.10/site-packages/pywinctl/_pywinctl_linux.py", line 763, in getAppName
pid = EWMH.getWmPid(self._hWnd)
File "/home/omlins/.local/lib/python3.10/site-packages/ewmh/ewmh.py", line 400, in getWmPid
return self._getProperty('_NET_WM_PID', win)[0]
TypeError: 'NoneType' object is not subscriptable
NOTE: The error occurred also when having a window open created with turtle
. Thus, the problem does not only occur with PySimpleGUI
, but probably with all GUIs that underneath rely on tkinter
.
I'm creating a script that would allow me to activate a specific set of windows, however it doesn't seem to cooperate with KDE when using setActiveWindow.
I'm currently running Debian 10 Buster with KDE 5 Plasma as my desktop environment. When I tried using setActiveWindow all it would do was highlight the programs in my task bar. I am certain that window activation was possible in KDE through the Xlib library because the xdotool command was able to activate the windows without problem.
I wrote a small script comparing the use of both setActiveWindow and xdotool and tested in on KDE, Gnome and Xfce, for the later two ewmh seems to work fine without issue:
from ewmh import EWMH
from time import sleep
from os import system
from sys import argv
user_input = argv[1]
mode = argv[2]
ewmh = EWMH()
the_list = ewmh.getClientList()
def use_ewmh(): #using setActiveWindow, Python Xlib implementation
for i in the_list:
if mode == "0": #run "python3 test.py 0 0"
sleep(1)
ewmh.setActiveWindow(i)
ewmh.display.flush()
elif str(ewmh.getWmName(i)).count("Calc"): #run "python3 test.py 0 1"
ewmh.setActiveWindow(i)
ewmh.display.flush()
def use_xdotool(): #using xdotool windowactivate, C implementation
for i in the_list:
the_id = str(i).find('0x')
the_string = str(int(str(i)[the_id:the_id+10], 16))
if mode == "0": #run "python3 test.py 1 0"
sleep(1)
system("xdotool windowactivate " + the_string)
elif str(ewmh.getWmName(i)).count("Calc"): #run "python3 test.py 1 1"
system("xdotool windowactivate " + the_string)
if user_input == "0":
use_ewmh()
else:
use_xdotool()
I've recorded the results and the can be viewed here:
https://www.youtube.com/watch?v=adgIoy7l1TU
File "/home/avasam/.local/lib/python3.9/site-packages/ewmh/ewmh.py", line 257, in getClientListStacking
return [self._createWindow(w)
TypeError: 'NoneType' object is not iterable
It seems self._getProperty('_NET_CLIENT_LIST_STACKING')
returns None
in a WSLg environment.
In the following:
def getWmWindowType(self, win, str=False):
"""Get the list of window types of the given window (property _NET_WM_WINDOW_TYPE).
:param win: the window object
:param str: True to get a list of string types instead of int
:return: list of (int|str)"""
types = self._getProperty('_NET_WM_WINDOW_TYPE', win)
if not str: return types
return map(self._getAtomName, wtypes)
This seems to be a bug to me where wtypes
is used at the last line instead of merely types
but that bug hasn't bitten me yet so I'm not sure if this intended but it seems quite unlikely to be intended to me.
There is currently no way to get access to the _NET_DESKTOP_NAMES property.
I may try to implement it myself, if you wish.
Hi,
we're using pyewmh for a long time on our build server to simulate GUI events.
But since pyewmh-0.1.5 something significant must have been changed. We're no longer able to use ewmh on our build server:
vagrant@vagrant-ubuntu-saucy-64:~$ python3
Python 3.3.2+ (default, Feb 28 2014, 00:52:16)
[GCC 4.8.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ewmh
>>> l_ewmh = ewmh.EWMH()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.3/dist-packages/ewmh/ewmh.py", line 50, in __init__
self.display = _display or display.Display()
File "/usr/local/lib/python3.3/dist-packages/Xlib/display.py", line 89, in __init__
self.display = _BaseDisplay(display)
File "/usr/local/lib/python3.3/dist-packages/Xlib/display.py", line 71, in __init__
protocol_display.Display.__init__(self, *args, **keys)
File "/usr/local/lib/python3.3/dist-packages/Xlib/protocol/display.py", line 132, in __init__
auth_prot_data = auth_data)
File "/usr/local/lib/python3.3/dist-packages/Xlib/protocol/display.py", line 1033, in __init__
display.send_and_recv(request = -1)
File "/usr/local/lib/python3.3/dist-packages/Xlib/protocol/display.py", line 573, in send_and_recv
raise self.socket_error
Xlib.error.ConnectionClosedError: Display connection closed by server
>>>
vagrant@vagrant-ubuntu-saucy-64:~$ echo $DISPLAY
localhost:10.0
vagrant@vagrant-ubuntu-saucy-64:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 13.10
Release: 13.10
Codename: saucy
I've no problem running l_ewmh = ewmh.EWMH()
on the desktop, but on build server it fails. Installation of pyewmh-0.1.5 on a clean build server looks like this:
Collecting ewmh
Downloading ewmh-0.1.5.tar.gz
Collecting python-xlib (from ewmh)
Downloading python_xlib-0.17-py3-none-any.whl (119kB)
Requirement already satisfied (use --upgrade to upgrade): six>=1.10.0 in /usr/local/lib/python3.3/dist-packages (from python-xlib->ewmh)
Installing collected packages: python-xlib, ewmh
Running setup.py install for ewmh: started
Running setup.py install for ewmh: finished with status 'done'
Successfully installed ewmh-0.1.5 python-xlib-0.17
Any ideas what's wrong?
Thanks in advance.
To avoid confusion, please edit the description of the SourceForge project to point to github, and say that further development is taking place here.
Presence of
x should be 1<<8
y 1<<9
width 1<<10
height 1<<11
app source 1<<12
The EWMH spec apparently means the first bit in a byte to be bit 0, not bit 1.
I think i found an bug at the getWmWindowTypes function:
`def getWmWindowType(self, win, str=False):
"""Get the list of window types of the given window (property _NET_WM_WINDOW_TYPE).
:param win: the window object
:param str: True to get a list of string types instead of int
:return: list of (int|str)"""
types = self._getProperty('_NET_WM_WINDOW_TYPE', win)
if not str: return types
return map(self._getAtomName, wtypes)`
types at line 7 must be wtypes or wtypes at last line types. or not?
I'm making an script that restarts programmes - before I kill them I save the (wm_name, x, y, width, height) using ewmh.
Is there a way to set window geometry using ewmh ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.