This is bad behavior, and can also cause us to get in an infinite loop
if an OR window is mapped and unmapped in quick succession. This
sequence causes a MapNotify followed by an UnmapNotify, and when
processing the events, we'll call XMapWindow, XUnmapWindow, which will
put another set of MapNotify, UnmapNotify events in our queue, which we
then process by calling XMapWindow, XUnmapWindow, and so it goes
forever, or at least some scheduler uncorks us by making us call
XMapWindow when the window is already mapped, or XUnmapWindow when the
window is already unmapped.
We can stop this madness by simply making sure never to call neither
XMapWindow or XUnmapWindow on OR windows, which is the correct thing to
do anyway.
In gnome-shell, we have a feature where the user can unmaximize windows
by dragging them from the panel above the window. With accurate
anchoring, this looks really weird as the cursor is now "detached" from
the window. Detect this case and put the cursor in the middle of the
window titlebar instead.
This seems to be more accurate with what we currently see in
GNOME. Without having the app expose this information to us, it might be
a better idea to use the default frame style for this information instead.
The cursor was anchored wrongly when trying to unmaximize windows from
dragging them from the top of the screen because of a few think-o's and
some code that forgot to be updated when we moved to the frame rect
coordinate system.
The cursor is still offset for windows that start dragging from the top
panel. This is technically correct, but looks wrong. We'll fix this in
the next commit.
The existing workspace management code is quite hairy, with plenty of
logic inline in all of window.c, workspace.c, and screen.c, making it
hard to understand or make changes to, since you might forget to change
several of the other places the code was around.
Rewrite the internal workspace management logic so that it's
centralized and all in window.c. Document the invariants we need to
maintain, and ensure that these invariants are properly kept, with
asserts in various places.
Extensive testing on gnome-shell did not bring up any issues, and this
is a considerable cleanup.
MetaGrabOp is painful and tedious to work with, because it's a
sequential series of values, meaning we have to use a giant unreadable
switch statement to figure out some basic things about the value.
To solve this, modify the encoding for MetaGrabOp and for the specific
window grab operations so that they're a set of bitflags that we can
easily check.
It turns out that Clutter doesn't actually filter NumLock / ScrollLock /
CapsLock from button events due to its terrible event translation code.
Check only the grab mods to check if it's unmodified.
Instead of returning a value based on whether or not we handled it, we
have this logic: either we have taken a grab on the window, in which
case we have a grab op and have handled it ourselves, or we did not take
a grab and *need* to replay the event to the window.
Handle this in events.c by checking the grab operation in the same way
that we check the other grab ops.
This is an accidental regression from 7a109a1. If we mark the event as
handled, then we *need* to set grab_op, or do some other sort of
behavior, since we have a grab.
On X11 this works because only emulated pointer events are listened for. On
wayland, the single touch behavior must be enforced in touch events, ignoring
every other sequence.
https://bugzilla.gnome.org/show_bug.cgi?id=733631
When a Wayland window acks our arrangement and we don't really have
anything to modify, we'll pass a sole flag of META_IS_WAYLAND_RESIZE
to meta_window_move_resize_internal using a garbage rect. The existing
code to calculate the new rectangle couldn't really handle this case,
and so the garbage rectangle accidentally got stored. Revamp the flag
checks to be more clear about it.
This fixes the weird positioning issues that sometimes appear when
resizing weston-terminal among others.
This code was supposed to refresh our default icons when the theme
changed, but it actually was a no-op, since the default icons are cached
in a static variable in MetaUI.
I'm not sure the fact that the fallback icons don't update when the
theme changes is an important enough use case to keep working, but I'm
keeping the skeleton function there in case somebody wants to actually
fix it properly.
This makes sure that we see them for Wayland clients as well, and don't
time out and crash when we're accessing an invalid window / surface.
Spotted-by: Rui Matos <tiagomatos@gmail.com>
Since Wayland configures are more of a hint to the client than anything,
we don't want to save the unconstrained rect when we're just hinting to
the client that it should resize, since it could ignore us. This would
get us stuck in a loop, since meta_window_move_resize_now would use the
unconstrained_rect to resize, and we don't remove the resize from the
queue if we have an outstanding request like that.
This fixes a bunch of traffic / CPU usage when trying to resize
weston-terminal.
For XWayland, we need to make sure to send out mouse events on O-R
windows, otherwise they won't get motion or button events.
The comment mentions being eaten for the compositor, but we already
bypass the compositor for all events that have a window. The return
value just controls whether we pass them to Wayland.
The output_id is more of an opaque identifier for the monitor, based on
its underlying ID from the windowing system. Since we also use the term
"output_id" for the output's index, rename our use of the opaque cookie
"output_id" to "winsys_id".
Some plugins and extensions want to be able to know when the sticky
field of a window changes, so add a property for it and allow them
to connect to the notify::on-all-workspaces signal.
When workspaces-only-on-primary is set and a window is moved back to the
primary, we also move it to the active workspace to avoid the confusion
of a visible window suddenly disappearing when crossing the monitor border.
However when the window is not actually moved by the user, preserving the
workspace makes more sense - we already do this in some cases (e.g. when
moving between primary monitors), but miss others (unplugging the previous
monitor); just add an explicit user_op parameter as used elsewhere to cover
all exceptions.
https://bugzilla.gnome.org/show_bug.cgi?id=731760
Remember the last monitor a window was moved to by user action and
try to move it back on monitor changes; this should match user
expectations much better when a monitor is unplugged temporarily.
https://bugzilla.gnome.org/show_bug.cgi?id=731760
When workspaces-only-on-primary is set, a window can be on all
workspaces either because it is on a non-primary workspace, or
because it was explicitly made sticky. Only the latter is reflected
in _NET_WM_STATE, but both will result in a "magic" _NET_WM_DESKTOP,
which we (and probably other WMs) use to set the initial sticky state.
So to avoid confusing other WMs (or ourselves), make sure to only
have _NET_WM_STATE_STICKY reflected in _NET_WM_DESKTOP when unmanaging.
Window state like maximization and minimization should be preserved
over restarts - in a patch review, this would qualify as "needs-work",
so revert the cleanup until the issues are fixed.
This reverts commit dc6decefb5.