This commit implements support for HiDPI rendering for wayland. X11
should be unaffected by this.
It is implemented by scaling everything that's rendered by a scale
factor that's obtained from the wayland protocol. All sizes before
rendering remain the same, so the same settings should provide the same
output for different scaling factors, only scaled by that factor.
- Get the window with keyboard focus using XGetInputFocus() instead of
_NET_ACTIVE_WINDOW
- Handle edge cases of keyboard/mouse focus being on different X screen
- Set sane default in case the active monitor can't be determined
(fixing issue #762)
This commit adds an output struct which abstracts the X11 specific
functions and makes it possible to easily create a drop-in wayland
output.
It also fixes a bug in wayland where notifications won't disappear.
This is because wayland doesn't give access to user input when a
client is not in focus. This way it seems like the user is always
idle. The idle functionality is now disabled in Wayland until proper
support is added.
The timeline of this issue is as follows:
In 7a094bc a call to XClearWindow/XFlush was added as part of RGBA
support.
Afterwards, I noticed that there is some noticeable flicker while
redrawing for large notifications, so I foolishly removed both of these
calls without considering the full effects.
As a result when redrawing notifications 'stack up' with each-other.
After a testing it seems that the XFlush call that was causing
the flicker is not necessary and XClearWindow works without it.
Fixes#728
This reverts commit 7a094bc702149104cd4049281a7dd9ed0ab76c89.
This commit caused a flicker effect every time the window was redrawn,
reverting it for now.
In dwm and similar window managers, it's common to often have empty
tags, and navigate to them with the intent to create clients there. If I
navigate to one of those empty tags with a dunst notification visible
and follow=keyboard set, the notification warps over to the default
screen. If I then open a client, it then warps back, which is pretty
jarring.
This is mostly an artefact of the implementation of follow=keyboard --
if we fail to get a focused window, we use the default screen. However
this case isn't necessarily really a "failure" on window managers like
dwm where it's a common occurrence to end up with no clients on the
screen, whereas that would be significantly rarer on (say) GNOME or KDE.
A guess that's more likely to fit user expectations is falling back to
where the mouse pointer currently is, since this indicates the currently
focused monitor that the window manager would create a client on. This
avoids warping back to that monitor again when a client is created.
The user provides a comma-separated list of valid mouse actions
that will be performed one after another when a notification is
clicked. If any one of the provided actions is invalid, the value
reverts to its default state.
IceWM does not send PropertyNotify when exiting fullscreen. As a
band-aid solution also re-check the fullscreen status on ConfigureNotify
events. We're receiving them already so a few extra checks should not be
noticeable in any case.
Fixes#613
Draw should not be called when there are no notifications in the queue.
This for unknown reasons causes a crash the next time we attempt to get
the currently active window with a BadValue error from
XGetWindowProperty.
Fixes#630.
In `x_parse_geometry` we modified the global settings struct for
negative width instead of updating it in the struct that is currently
being constructed.
As a result the negative_width field was always false as it was being
overwritten by the struct assignment after the functions return.
Fixes#628
PropertyNotify events are used primarily to detect active screen changes
when follow mode is used but now we also need them to receive resource
manager events in order to update the dpi value.
When changing values with xrdb on the command line, an XEvent is
triggered on the "RESOURCE_MANAGER" atom.
But xlib just doesn't care. XResourceManagerString() will still report
the old values. Also XrmGetDatabase() won't help out.
So, when we receive a PropertyNotify for the resource manager atom, we
have to manually query its contents, convert it to a DB and replace it
in the display object.
This allows, that any method just can call XrmGetDatabase() and get the
latest values.
This allows to update the DB on the xctx.dpy object. Crawling the string
from xctx.dpy will always return the xdefaults string, which represents
the defaults from the initialisation, but not with any other updates.
The Xft.dpi value is one way to set the dpi of the X11 display. Querying
this value requires much overhead. Therefore we have to cache this.
Previously we did just query it at the beginning and ignored further
changes.
As there is no native signal to catch a change in its xrdb value, we
have to rely on the root window's PropertyNotify event and filter there
the RESOURCE_MANAGER atom.
This will get hooked up later.
When changing the DPI via xrandr --dpi <DPI>, xrandr will send a
RRScreenChangeEvent and the DPI value should get adjusted.
Falsely, we thought randr_update() would catch up and query the right
monitor values. But nothing changes, because we query the
XRRMonitorInfo. The monitor info contains the real physical width and
height of the monitor's screen.
But xrandr --dpi only changes the - let's say - virtual screen size of
the virtual overall screen (and therefore changing the DPI to the
matching value).
Important commands to understand:
- Changes dpi of the virtual screen
xrandr --dpi
- Gives info about the "virtual" screen size (used by DisplayWidth)
xdpyinfo | grep -B1 resolution
- Gives info about the "physical" screen size (used by XRRMonitorInfo)
xrandr -q
I know, that I'm probably not right and might not understand the topic
in its full size yet[0]. But I'm 100% sure, that the terms "monitor",
"screen", "screens", "output" and "display" do not have a consistent
naming scheme.
[0] https://twitter.com/dechampsgu/status/857924498280124416Fixes#382
If n < screens_len, screens_len did not get updated. So boundary
checks wouldn't catch, if screens between n and screens_len are
accessed. This will prevent such an error type in the future.
Just recently, I started using g_return_val_if_fail as a brief assertion
checker. It'll also exit the function with a specified return value.
But actually this introduces some weird behavior. It's configurable by
environment variables and it'll print out a log message, if the
expression didn't validate properly. But some of these assertions are
actually ment to be silent.
Using a simple macro makes it simple to structure the assertions and its
return values in a block at the start of a function or anywhere else.