The order and way include macros were structured was chaotic, with no
real common thread between files. Try to tidy up the mess with some
common scheme, to make things look less messy.
This moves following objects from MetaScreen to MetaDisplay
- workareas_later and in_fullscreen_later signals and functions
- startup_sequences signals and functions
- tile_preview functions
https://bugzilla.gnome.org/show_bug.cgi?id=759538
- Moved xdisplay, name and various atoms from MetaDisplay
- Moved xroot, screen_name, default_depth and default_xvisual
from MetaScreen
- Moved some X11 specific functions from screen.c and display.c
to meta-x11-display.c
https://bugzilla.gnome.org/show_bug.cgi?id=759538
When closing a window and showing a new one, the new one may not be
granted input focus until it gets a buffer on Wayland.
If another window is chosen to receive focus and raised on top of stack,
the newly mapped window is focused but placed underneath that other
window.
Meaning that for Wayland surfaces, we need to defer adding the window to
the stack until we actually get to show it, once we have a buffer
attached.
Rather that checking the windowing backend prior to decide if a window
is stackable or not, introduce a new vfunc is_stackable() which tells
if a window should be added to the stack regardless of the underlying
windowing system.
Also add meta_window_is_in_stack() API rather than checking the stack
position directly (replacing the define WINDOW_IN_STACK only available
in stack.c) and remove a window from the stack only if it is present
in the stack, so that the test in meta_stack_remote() becomes
irrelevant.
https://bugzilla.gnome.org/show_bug.cgi?id=780820
Commit fcc7501eb8 had the side-effect of
stacking fullscreen windows below docks which went unnoticed since we
don't use docks in GNOME anymore.
Instead of re-introducing the fullscreen layer, which we don't need
otherwise, we can fix this issue by ensuring we stack docks below all
other windows when the monitor they're on is marked fullscreen. This
has the added benefit that the visibility rule for 3rd party docks
becomes the same as gnome-shell's chrome.
https://bugzilla.gnome.org/show_bug.cgi?id=772937
This layer isn't really being used and in fact, it causes
meta_stack_get_default_focus_window() to return a fullscreen window
even if the naturally topmost window in the stack isn't a fullscreen
one.
Note that commit a3bf9b01aa changed how
we choose the default focus window from the MRU to the topmost in the
stack.
https://bugzilla.gnome.org/show_bug.cgi?id=768221
Stacking hidden X windows below the guard window is a necessity to
ensure input events aren't delivered to them. Wayland windows don't
need this because the decision to send them input events is done by us
looking at the clutter scene graph.
But, since we don't stack hidden wayland windows along with their X
siblings we lose their relative stack positions while hidden. As
there's no ill side effect to re-stacking hidden wayland windows below
the X guard window we can fix this by just doing it regardless of
window type.
https://bugzilla.gnome.org/show_bug.cgi?id=764844
Since g_array_append_val isn't smart enough to do a proper upcast, we
have to do it manually, lest we get junk.
This fixes various RAISE_ABOVE: window not in stack: 0x8100c8003
warnings that appear on 32-bit systems.
The main monitor of a window is maintained as 'window->monitor' and is
updated when the window is resized or moved. Lets avoid calculating it
every time it`s needed.
https://bugzilla.gnome.org/show_bug.cgi?id=744934
The only time we ever execute this code is when we're minimizing or
hiding a window, in which case we should respect stacking order.
This fixes weird "bugs" where windows from the same app magically pop up
over other windows.
A window may be hidden even if not minimized itself, for instance
when an ancestor is minimized. As meta_window_focus() will refuse
to actually focus the window in that case, don't pick it in the first
place.
https://bugzilla.gnome.org/show_bug.cgi?id=751715
With the change to how hidden windows are stacked, the position
of the guard window with respect to the hidden windows got flipped
and the guard window was at the bottom of everything; fix it to
be on top of the hidden windows.
https://bugzilla.gnome.org/show_bug.cgi?id=737233
Restacking the frame for a window while unmanaging the window is
harmless, but for undecorated (in particular, client-side-decorated)
windows, this causes problems because the window is typically
destroyed by the client immediately after withredrawing the window.
Skip windows flagged as being unmanaged when assembling the new
stack and when comparing the old order to the new stack.
Add a stacking test for this.
stack.c:sync_stack_to_xserver had both code for assembling the desired stack, and
code for enforcing the desired stack on the actual stack of X and Wayland windows;
the latter part is properly the domain of stack-tracker.c; moving the code to
apply the stack there both simplifies it and keeps stack.c more manageable.
https://bugzilla.gnome.org/show_bug.cgi?id=736559
There was still code in stack.c to handle skipping override-redirect windows,
but since quite a while ago, meta_stack_add() is not called for OR windows
since they are outside our stacking control. Add an assertion and remove
unnecessary code.
https://bugzilla.gnome.org/show_bug.cgi?id=736559
stack.c kept it's own record of the last stacking it requested, so that
restacking could be done with minimal moves, but we already have a better
view of the stacking order with the stack tracker, so use that instead.
This allows eliminating the special case for the first restack.
https://bugzilla.gnome.org/show_bug.cgi?id=736559
Since MetaStackTracker is the code that knows about the current X stacking order
and the relationship between X windows and Wayland windows, it's cleaner to
encapsulate stack manipulation in MetaStackTracker rather than have the calling
code make the X calls and only call into MetaStackTracker to inform it about
the changes.
https://bugzilla.gnome.org/show_bug.cgi?id=736559
Putting X windows and pointers to MetaWindows into a union had a number of
problems:
- It caused awkward initialization and conditionalization
- There was no way to refer to Wayland windows (represented by
MetaWindow *) in the past, which is necessary for the MetaStackTracker
algorithms
- We never even cleaned up old MetaStackWindow so there could be
records in MetaStackWindow pointing to freed MetaWindow.
Replace MetaStackWindow with a 64-bit "stack ID" which is:
- The XID for X Windows
- a "window stamp" for Wayland windows - window stamps are assigned
for all MetaWindow and are unique across the life of the process.
https://bugzilla.gnome.org/show_bug.cgi?id=736559
We can enter weird states where get_default_window is called during
window unmanagement, before the window has been fully removed from
the stack. Make sure these windows are *never* returned from
get_default_window, as focusing them can cause an assertion fail,
or worse.
The code that restacks X11 windows at the end first tracks any
old windows we know about, and then handles any windows created.
It starts when it ended, and then walks forwards and then
back looking for the first X11 window it doesn't know about.
However, when there aren't any X11 windows, it flies off the end
of the array and starts looking through random memory.
When it finds the X11 window, it then goes through and then tries
to restack the remaining windows according to how we've sorted
them.
Unfortunately, META_WINDOW_CLIENT_TYPE_X11 is 0, which is quite
common in random memory we have lying around, so we enter that
path and then just crash.
Fix the buffer overrun by adding the proper bounds check to the
search.
You can easily reproduce this by opening a menu while bloatpad
is full-screen. Why it only crashes when full-screen and not
when a standard window, I have no idea.
For clarity, rename meta_window_get_outer_rect() to match terminology
we use elsewhere. The old function is left as a deprecated
compatibility wrapper.
Since this is stored in an array full of data that will be copied
around, we can't rely on pointer addresses for every item in a stack
not changing.
I don't see any reason that we even have a weak pointer, either.
This code looks safe to me without it.
This breaks down the assumptions in stack-tracker.c and stack.c that
Mutter is only stacking X windows.
The stack tracker now tracks windows using a MetaStackWindow structure
which is a union with a type member so that X windows can be
distinguished from Wayland windows.
Some notable changes are:
Queued stack tracker operations that affect Wayland windows will not be
associated with an X serial number.
If an operation only affects a Wayland window and there are no queued
stack tracker operations ("unvalidated predictions") then the operation
is applied immediately since there is no server involved with changing
the stacking for Wayland windows.
The stack tracker can no longer respond to X events by turning them into
stack operations and discarding the predicted operations made prior to
that event because operations based on X events don't know anything
about the stacking of Wayland windows.
Instead of discarding old predictions the new approach is to trust the
predictions but whenever we receive an event from the server that
affects stacking we cross-reference with the predicted stack and check
for consistency. So e.g. if we have an event that says ADD window A then
we apply the predictions (up to the serial for that event) and verify
the predicted state includes a window A. Similarly if an event says
RAISE_ABOVE(B, C) we can apply the predictions (up to the serial for
that event) and verify that window B is above C.
If we ever receive spurious stacking events (with a serial older than we
would expect) or find an inconsistency (some things aren't possible to
predict from the compositor) then we hit a re-synchronization code-path
that will query the X server for the full stacking order and then use
that stack to walk through our combined stack and force the X windows to
match the just queried stack but avoiding disrupting the relative
stacking of Wayland windows. This will be relatively expensive but
shouldn't be hit for compositor initiated restacking operations where
our predictions should be accurate.
The code in core/stack.c that deals with synchronizing the window stack
with the X server had to be updated quite heavily. In general the patch
avoids changing the fundamental approach being used but most of the code
did need some amount of re-factoring to consider what re-stacking
operations actually involve X or not and when we need to restack X
windows we sometimes need to search for a suitable X sibling to restack
relative too since the closest siblings may be Wayland windows.
Mutter previously defined display->focus_window as the window that the
server says is focused, but kept display->expected_focus_window to
indicate the window that we have requested to be focused. But it turns
out that "expected_focus_window" was almost always what we wanted.
Make MetaDisplay do a better job of tracking focus-related requests
and events, and change display->focus_window to be our best guess of
the "currently" focused window (ie, the window that will be focused at
the time when the server processes the next request we send it).
https://bugzilla.gnome.org/show_bug.cgi?id=647706
Trying to track the fullscreen status outside of Mutter, as GNOME Shell
was doing previously, was very prone to errors, because Mutter has a
very tricky definition of when a window is set to be fullscreen and
*actually* acting like a fullscreen window.
* Add meta_screen_get_monitor_in_fullscreen() and an
::in-fullscreen-changed signal. This allows an application to
track when there are fullscreen windows on a monitor.
* Do the computation of fullscreen status in a "later" function that
runs after showing, so we properly take focus into account.
* To get ordering of different phases right, add more values
to MetaLaterType.
* Add auto-minimization, similar to what was added to GNOME Shell
earlier in this cycle - if a window is set to be fullscreen, but
not actually fullscreen, minimize.
https://bugzilla.gnome.org/show_bug.cgi?id=649748