Today I learnt that _NET_WM_STATE_STICKY means something else than I
previously thought.
ICCCM and EWMH support virtual desktops that are larger than the actual
screen. The idea is that one can scroll through this virtual desktop,
which means that e.g. all windows move to the left, so one can see the
windows that are further to the right.
_NET_WM_STATE_STICKY indicates that a window is sticky. This means that
it does not scroll with the virtual desktop, but instead sticks to its
current position.
In AwesomeWM, we use a different definition. A sticky window is always
visible, even when it is not tagged with any of the currently selected
tags. This behaviour is indicated in EWMH with a special value of
_NET_WM_DESKTOP. This commit updates the code to actually set this
special value.
This fixes attaching tabs in Google Chrome when the "target window" is
sticky (in the AwesomeWM sense).
Fixes: https://github.com/awesomeWM/awesome/issues/2652
Signed-off-by: Uli Schlachter <psychon@znc.in>
The list of supported formats of the selection is queried by requesting
the target TARGETS. This target is a list of ATOMs and needs special
handling which is what this commit adds.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Incremental transfers are required to be supported. This commit adds
that necessary support to awesomeWM.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit adds support for simple selection transfers. INCR support is
still missing. The API is that a selection getter object emit the "data"
signal when some data becomes available and "data_end" when all data was
received.
Signed-off-by: Uli Schlachter <psychon@znc.in>
So far they do not do match. The selection and target are specified and
a window is created for a transfer, but no transfer is actually started
yet.
Signed-off-by: Uli Schlachter <psychon@znc.in>
When the selection that is watched by an active selection watcher
changes, then the signal "selection_changed" is emitted on the watcher.
This signal has one boolean argument that indicates if the selection is
owned. This means that this argument is false when the selection owner
went away and the selection now has no owner at all.
Signed-off-by: Uli Schlachter <psychon@znc.in>
These objects are created via e.g. selection_watcher("CLIPBOARD") to
track the CLIPBOARD selection. They start watching when their .active
property is set to true and stop when this property is unset again.
This commit implements the Lua side of that: A list of active watchers
is kept and updated when needed.
The next commit will add the X11-side of this so that these objects
actually do something.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit adds the necessary method calls to setup the class and also
so that xfixes selection notify events can be handled. Currently, these
are empty functions, but later commits will fill them.
Signed-off-by: Uli Schlachter <psychon@znc.in>
No idea what "If the client has multiple classes" is supposed to refer
to, but this commit gets rid of that reference. Also, this commit
clarifies how to get the class and instance out of xprop.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Until now there wasn't much documentation available about how to use
these properties. With the new work on `awful.spawn` that rely more and
more on `awful.rules` integration, it is worth fixing.
This commit add a new documentation section and a future commit will
aggregate them to generate an index.
Previously, this function overwrote the value of its argument with the
result. After this change, the function merely changes the given
variable by the calculated argument.
Thus, the old behaviour is achieved by setting the variable to zero
before the call, which all callers already did. However, for most
callers this change means that a temporary variable can be removed and
instead xwindow_translate_for_gravity() will directly change the target
variable.
No change in behaviour intended.
Signed-off-by: Uli Schlachter <psychon@znc.in>
There are two ways in which the input focus can change: Lua can request
a change and the X11 server can inform us that the input focus changed
(because some application changed it).
In the first case, we still have to inform the X11 server about the
desired change, in the second case we must not to avoid races due to
X11's asynchronous nature.
However, there was a case where we screwed up: When a focus change is
still pending, meaning that Lua assigned the focus elsewhere, but we
have not yet sent this focus change to the X11 server, we could get an
event from the X11 server telling us that the focus changed. To make
sure that the pending focus change is not lost, we sent the focus change
out in this case (call to client_focus_refresh() in
event_handle_focusin()). After sending out this pending call, we updated
the internal state to record that whatever the X11 server just told us
had the focus. The intention was that our just sent-out focus change
will cause the X11 server to send a new event and our to-be-focused
client then has the focus.
However, if the pending focus change was for a client which only showed
up in this event loop iteration, the client was still banned. This means
that client_focus_refresh() would call client_unban() to be able to give
the focus to this client. However, since awesome (partly) allows to
"focus" currently banned clients, client_unban() recorded that there is
a pending focus change. This caused confusion later on.
In this specific bug, a main window opened a dialog, and when this
dialog was closed, a new dialog window was opened immediately. When the
first dialog was closed, Lua (the focus history) gave the input focus to
the main window. Now, a new dialog showed up and Lua focused it. Next,
we received the event from the X11 server telling us that the main
window was focused. Because there was still a pending focus change to
the new dialog window, event_handle_focusin() called
client_focus_refresh() to send out this focus change. This set
globalconf.focus.need_update to false and continued. However, because
the new dialog only just now appeared, it was still banned, meaning that
client_focus_refresh() had to call client_unban(). This set
globalconf.focus.need_update to true. Thus, when client_focus_refresh()
returned, globalconf.focus.need_update was incorrectly true. Next,
event_handle_focusin() recorded that the main window had the focus.
Thus, it now appeared as if there was a pending focus change for the
main window. Next, we got the event from the X11 server telling us that
the dialog is now focused, and because focus.need_update was set,
awesome now send out a focus change request for the main window.
Fix this race by unsetting globalconf.focus.need_update at the end of
client_focus_refresh() and not at the beginning, thus making sure that
client_unban() cannot set this flag again.
Fixes: https://github.com/awesomeWM/awesome/issues/2220
Signed-off-by: Uli Schlachter <psychon@znc.in>
When a window has a WM_TRANSIENT_FOR property that is later unset,
awesome would still keep c.transient_for pointing to the previous
"parent client". This commit fixes that.
First, property_update_wm_transient_for() is fixed so that it unsets
c->transient_for_window if the WM_TRANSIENT_FOR property is deleted.
Additionally, this then calls client_find_transient_for() to update the
c->transient_for pointer.
Secondly (and a bit unrelated), this changes client_find_transient_for()
so that it always sets c->transient_for. Previously, if updating this
property would introduce a cycle in the transient_for relation, it would
just leave c->transient_for with its old value. After this change, it
gets explicitly set to NULL instead.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This makes motif wm hints available on clients as c.motif_wm_hints.
Actually interpreting all the values is up to Lua. The definition of the
necessary properties is taken from motif.
Signed-off-by: Uli Schlachter <psychon@znc.in>
The getters for properties already get the object as their second
argument, so there is no need to get the object again from Lua.
Fixes: https://github.com/awesomeWM/awesome/issues/2299
Signed-off-by: Uli Schlachter <psychon@znc.in>
When a new client appears, we reparent its window into a window of our
choice so that we can add decorations. However, windows can be difficult
making the reparenting fail. For example, some snapshots of GTK+ set a
parent-relative background, which means that its parent windows have to
have the same depth as the window itself. This makes reparenting fail if
transparency is used/supported.
Make the failure mode... different, by checking if reparenting
succeeded. If it failed, we print an error message and unmanage the
window immediately. This means that those GTK+ windows just do not
appear at all, instead of behaving weirdly.
This idea of this patch came from i3.
Related-to: https://github.com/awesomeWM/awesome/issues/2279
Signed-off-by: Uli Schlachter <psychon@znc.in>
The systray_cleanup() function gives up the _NET_SYSTEM_TRAY_Sn
selection ownership and should be called only when Awesome exits.
Calling systray_cleanup() from drawin_systray_kickout() is not correct,
because drawin_systray_kickout() is called when the system tray window
needs to be hidden, including the case when the last tray icon was
removed and the tray became empty.
Fixes: https://github.com/awesomeWM/awesome/issues/2301
Signed-off-by: Sergey Vlasov <sigprof@gmail.com>
* Make fake screens permanent
Before this, screen_scan() made sure that awesome's information about
available screens conforms to what the X11 server reports. Since fake
screens are, well, fake, this meant that they were deleted.
This commit marks fake screen and handles them specially in
screen_scan() so that they are not deleted.
Note that I did not test this commit at all since I still haven't
figured out how to test RandR stuff without actually messing with
hardware.
Thanks to @madduck for bringing this up and making me fix this long
standing "huh? is that really supposed to work like that?".
Signed-off-by: Uli Schlachter <psychon@znc.in>
Up to now, we always asked the X11 server for color allocation ("which
pixel value corresponds to (r,g,b)?", an AllocCollor request).
This commit adds direct support for TrueColor and DirectColor visuals.
In such a visual, the X11 server gives tells us where the red, green,
and blue color components are in a pixel value and we can then just
directly compute the pixel value.
Additionally, this commit adds code that assumes that in a depth=32
visual, the remaining values (after handling red, green, blue) is the
alpha channel for colors. Thus, this adds support for transparent client
borders.
This commit also touches code for the systray. However, the systray must
always use the X11 server's default visual and that one always(?) has
depth=24, i.e. does not support an alpha channel. Thus, the systray
background still cannot be transparent.
Also, in theory this commit should support visuals where some color
component does not have 8 bits, for example RGB565. However, this is
just theoretic and I have no idea how to actually test this (without
jumping through too many hoops).
Fixes: https://github.com/awesomeWM/awesome/issues/162
Signed-off-by: Uli Schlachter <psychon@znc.in>
When a screen is in the process of being removed, it is still valid, but
no longer in the global list of screens (globalconf.screens). In this
time frame, trying to swap screens could cause a NULL pointer
dereference.
Fix this by throwing a Lua error in this case instead.
Fixes: https://github.com/awesomeWM/awesome/issues/2110
Signed-off-by: Uli Schlachter <psychon@znc.in>
_NET_WM_STATE could contain _NET_WM_STATE_HIDDEN, which we interpret as
minimized. Minimized clients have WM_STATE set to WM_STATE_ICONIC, but
the code in client_manage() would later overwrite this to
WM_STATE_NORMAL.
Fix this by setting the initial WM_STATE_NORMAL by doing so before
processing _NET_WM_STATE.
Fixes: https://github.com/awesomeWM/awesome/issues/2095
Signed-off-by: Uli Schlachter <psychon@znc.in>
The screen object can be indexed by strings to find a screen via some
RANDR output name. However, if a string is used which does not
correspond to a known output, the code just falls through to a function
which will complain "string provided, userdata expected".
This commit provides a slightly more useful error message instead.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This function tried to move the client to its new screen based on
shifting around its current geometry. However, it assumed that the
client was actually visible on its current screen, which is not always
the case.
Fix this by just forcing the client into its new screen if our moving
approach does not work.
This also reverts commit d5e365804c which
is no longer necessary. This commit only hid the issue (partly).
Fixes: https://github.com/awesomeWM/awesome/issues/318
Signed-off-by: Uli Schlachter <psychon@znc.in>
The code here made sure that clients were not moved outside of the root
window. However, that's not enough, because clients can still end up
inside the root window, but outside of anything that is visible in some
output. Thus, just remove this.
Related-to: https://github.com/awesomeWM/awesome/issues/318
Signed-off-by: Uli Schlachter <psychon@znc.in>
Aborting the process is sometimes a bit harsh for a failed assertion.
This adds a non-fatal assert() macro called "check()" and uses it in
some places where we might be able to survive the error.
Signed-off-by: Uli Schlachter <psychon@znc.in>