I am developing a module with Python, and I would like to figure out a way to get the monitor resolution minus the taskbar without any user interaction and preferably in a way that doesn't interfere with the visual interface. If I can just get the taskbar size and position, I can simply subtract it from the monitor resolution easily. However, I cannot seem to find a way.
In Windows, I am able to use the win32api
module and use GetMonitorInfo
to get the monitor resolution. However, I have yet to figure out some way to do this in Ubuntu, or Linux in general. If you also have a way to do this in macOS, that would be nice to know as well, but is not necessary for this question.
I would like to support as many desktop environments as possible, but I realize how difficult it would be to do so, since each one may have their own solution. Considering this, I would prefer to start with these desktop environments:
- KDE
- XFCE
- Gnome
- Cinnamon
If this requires some external programs to get it, I would prefer to use something that comes with the desktop environment or operating system.
This is what has been asked and I will be focusing on that through out this answer based on what I've found. Getting taskbar size and position was an original idea, but as has been discussed in the comments, this will be difficult to implement without knowing lots of information - which panel or dock is running, do they have
_NET_WM_STRUT
property set, do they expose that information via GSettings database or other methods. I am certain it is not impossible, but is rather difficult.NET_WORKAREA property
According to specifications for the root window, _NET_WORKAREA is defined as so:
There's a few points to note:
_NET_WM_STRUT
or_NET_WM_STRUT_PARTIAL
are properties that are set by docks and panels. This means, that if the panel or dock don't set it, they will basically behave like a normal window that just sits above all the others ( and making the users potentially annoyed1 ). That said, this is good enough for us. I've tested this property on Cinnamon, LXQt, and XFCE on top of Ubuntu 18.04. In all instances, the docks and panels properly informed the window manager of their strut area. That means,_NET_WORKAREA
will work for you in 99% of the cases.This property can be queried in shell via
xprop
utility over the root window.That's the output with my dual monitor setup, with two monitors aligned along the top, a dock and top panel. If you notice only the first four values are significant, and the other four are repeated. Of particular interest is
3120
and974
. That's the value we're interested in. The first two tell us where the desktop's left most corner starts. My top panel takes up 32 points, hence desktop's left most corner starts all the way on the left, with offset downward 32 points. Offset from the bottom usually doesn't matter for windows - they'll fill the workarea that's available.If I put the dock on the right side of the primary monitor, you will notice that width has decreased, but height has:
The change in height is 44 points. Add another 32 (the size of top panel window) to that, and you'll get 1050 exactly the geometry of my desktop (note the 3120 from before when there was no dock to the size, so full desktop width was being used ):
Python and
xprop
The
xprop
command above comes with most desktops, and belongs to x11-utils package, so if you're targeting major Debian-based systems, you should have it available at most times. What I would do is use Python's subprocess, and utilize eithersubprocess.check_output()
orsubprocess.run()
command and parse the output viare
module.Python and Gdk
Alternative ( and usually my preferred way ) would be to utilize Gdk library which is closely related to other GNOME project libraries. If you are developing a desktop application using Gtk, you already have the necessary tools available, so why not use them ? The tricky part is that you have to calculate workarea for each individual monitor.
The result of this program:
Issues
Now, remember I've mentioned I have dual monitors ? Such setup opens whole lot of possibilities, but also reveals certain odd behaviors.
Remember that I have a panel and a dock on one screen, and added for tests
xfce4-panel
on the other screen. The buggy results with Gdk is that second monitor work area did not get changed.xprop
also reported erroneous numbers - in the first output526
points of offset from the left were simply not true. In the last output, however, the vertical offset increased, which was the good thing - the extra width added byxfce4-panel
should be added to the total, and probably what helps is that my two monitors are aligned at the top.In other words, if your application is planning on determining the area without docks and panels, these methods will work best with single monitor setup. In dual monitor setup - results could potentially be inconsistent. Note that I am using Metacity Window Manager, and the bugginess could be attributed to that. However, I don't have a way to test other WM with dual monitor setup at the moment,so I'll leave this section as inconclusive.
TODO ( someday )
libx11 example in C or Python
dual monitor testing with alternative window manager
find dock and panel locations
Footnotes
1 Feature not documented, depends on user's amount of patience.