The windows in the background are ignored when the window is fullscreen.
However, we still would like to see the background if that window is
transparent.
* LibGUI: Verify m_window_id is not-zero in set_maximized
Window::set_maximized requires non-zero window id to be a valid call,
i.e. calling Window::show beforehand. A verify statement before the
server call can help developers by hinting correct usage.
* LibGUI: Paint background when the fullscreen window is transparent
The windows in the background are ignored when the window is fullscreen.
However, we still would like to see the background if that window is
transparent.
* Userland: Add ability to capture rectangular region in shot
A click and drag selectable, transparent, fullscreen window is
displayed with the command line argument -r for screenshots.
Previously, this mode would flash flush/repaint rects in yellow for
however it long it took for the compositor to replace the yellow with
the final image instead.
Now we usleep() for 10 ms when flashing, so you get a chance to see
the yellow. This immediately makes "flash flush" mode super useful. :^)
Because window states and various flags can affect the windows'
rendered areas it's safer to use the last computed occlusion rectangles
to invalidate areas on the screen that may have to be re-rendered due
to e.g. a window size change.
Fixes#6723
Depending on the driver, the second buffer may not be located right
after the first, e.g. it may be page aligned. This removes this
assumption and queries the driver for the appropriate offset.
Some devices may require DMA transfers to flush the updated buffer
areas prior to flipping. For those devices we track the areas that
require flushing prior to the next flip. For devices that do not
support flipping, but require flushing, we'll simply flush after
updating the front buffer.
This also adds a small optimization that skips these steps entirely for
a screen that doesn't have any updates that need to be rendered.
Also, make it return a reference as aside from only three special
situations (creating, destroying, and moving a window between stacks)
a window should always be on a window stack. Any access during those
brief situations would be a bug, so we should VERIFY this.
This solves two problems:
* A window was sometimes deemed occluded when the window rect was
entirely covered by other rectangles, transparent or opaque. This
caused a window to stop rendering even if a small portion was still
visible, e.g. when it was merely covered by a window shadow.
* The window switcher is interested in window updates even when a
window is entirely covered by another one, or when it is on another
desktop. This forces windows to be not occluded in those cases.
When using the Super+Tab hotkey then all windows will be displayed,
and we will switch to another virtual desktop if needed.
When using the Alt+Tab hotkey then only the windows on the current
desktop will be displayed.
This also adds the ability to query how many virtual desktops are
set up, and for the Taskbar to be notified when the active virtual
desktop has changed.
This creates a 2-dimensional array of WindowStack instances, one for
each virtual desktop. The main desktop 0,0 is the main desktop, which
is the desktop used for all stationary windows (e.g. taskbar, desktop).
When adding windows to a desktop, stationary windows are always added
to the main desktop.
When composing the desktop, there are usually two WindowStacks
involved. For stationary windows, the main desktop will be traversed,
and for everything else the current virtual desktop will be iterated.
Iteration is interweaved to preserve the correct order. During the
transition animation, two WindowStacks will be iterated at the same
time.
This patch adds the WindowServer::Animation class, which represents
a simple animation driven by the compositor.
An animation has a length (in milliseconds) and two hooks:
- on_update: called whenever the animation should render something.
- on_stop: called when the animation is finished and/or stopped.
This patch also ports the window minimization animation to this new
mechanism. :^)
We regularily need to flush many rectangles, so instead of making many
expensive ioctl() calls to the framebuffer driver, collect the
rectangles and only make one call. And if we have too many rectangles
then it may be cheaper to just update the entire region, in which case
we simply convert them all into a union and just flush that one
rectangle instead.
An Overlay is similar to a transparent window, but has less overhead
and does not get rendered within the window stack. Basically, the area
that an Overlay occupies forces transparency rendering for any window
underneath, which allows us to render them flicker-free.
This also adds a new API that allows displaying the screen numbers,
e.g. while the user configures the screen layout in DisplaySettings
Because other things like drag&drop or the window-size label are not
yet converted to use this new mechanism, they will be drawn over the
screen-number currently.
This enables the shot utility to capture all screens or just one, and
enables the Magnifier application to track the mouse cursor across
multiple screens.
This enables rendering of mixed-scale screen layouts with e.g. high
resolution cursors and window button icons on high-dpi screens while
using lower resolution bitmaps on regular screens.
This sets the stage so that DisplaySettings can configure the screen
layout and set various screen resolutions in one go. It also allows
for an easy "atomic" revert of the previous settings.
This allows WindowServer to use multiple framebuffer devices and
compose the desktop with any arbitrary layout. Currently, it is assumed
that it is configured contiguous and non-overlapping, but this should
eventually be enforced.
To make rendering efficient, each window now also tracks on which
screens it needs to be rendered. This way we don't have to iterate all
the windows for each screen but instead use the same rendering loop and
then only render to the screen (or screens) that the window actually
uses.
This patch moves the window stack out of WindowManager and into its own
WindowStack class.
A WindowStack is an ordered list of windows with an optional highlight
window. The highlight window mechanism is used during Super+Tab window
switching to temporarily bring a window to the front.
This is mostly mechanical, just moving the code to its own class.
By moving the logic to determine what window areas (shadow, frame,
content) into WindowFrame::opaque/transparent_render_rects we can
simplify the occlusion calculation and properly handle more
arbitrary opaque/transparent areas.
This also solves the problem where we would render the entire
window frame as transparency only because the frame had a window
shadow.
Problem:
- `static` variables consume memory and sometimes are less
optimizable.
- `static const` variables can be `constexpr`, usually.
- `static` function-local variables require an initialization check
every time the function is run.
Solution:
- If a global `static` variable is only used in a single function then
move it into the function and make it non-`static` and `constexpr`.
- Make all global `static` variables `constexpr` instead of `const`.
- Change function-local `static const[expr]` variables to be just
`constexpr`.
This commit unifies methods and method/param names between the above
classes, as well as adds [[nodiscard]] and ALWAYS_INLINE where
appropriate. It also renamed the various move_by methods to
translate_by, as that more closely matches the transformation
terminology.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.
See: https://spdx.dev/resources/use/#identifiers
This was done with the `ambr` search and replace tool.
ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
The previous names (RGBA32 and RGB32) were misleading since that's not
the actual byte order in memory. The new names reflect exactly how the
color values get laid out in bitmap data.
(...and ASSERT_NOT_REACHED => VERIFY_NOT_REACHED)
Since all of these checks are done in release builds as well,
let's rename them to VERIFY to prevent confusion, as everyone is
used to assertions being compiled out in release.
We can introduce a new ASSERT macro that is specifically for debug
checks, but I'm doing this wholesale conversion first since we've
accumulated thousands of these already, and it's not immediately
obvious which ones are suitable for ASSERT.
A window repaint may change the alpha value, resulting in a different
hit test outcome. In those cases, re-evaluate the cursor hit testing
after a window was painted, and update the cursor if needed.
I honestly don't know the internals of all this and what exactly is
going on, but this fixes compositing of the fullscreen window. By trial
and error I found that specifically m_invalidated_all needs to be set to
false, so it's probably different behaviour in prepare_dirty_rects(),
which depends on that...
Either way, the code composing all windows in non-fullscreen mode calls
Window::clear_dirty_rects() for each, so not doing that for the fullscreen
window as well seems like an oversight.
Fixes#4810.
We only cleared the area not covered by the backing bitmap if a
rendering rectangle intersected with the backing bitmap. But because
we are potentially calling the render function many times we need
to always clear the area not covered by the backing bitmap, whether
it intersects or not.
Fixes#5291
This implements simple window shadows around most windows, including
tooltips. Because this method uses a bitmap for the shadow bits,
it is limited to rectangular window frames. For non-rectangular
window frames we'll need to implement a more sophisticated algorithm.
This only renders the window frame once until the size of the window
changes, or some other event requires re-rendering. It is rendered
to a temporary bitmap, and then the top and bottom part is stored
in one bitmap as well as the left and right part. This also adds
an opacity setting, allowing it to be rendered with a different
opacity.
This makes it easier to enhance window themes and allows using
arbitrary bitmaps with e.g. alpha channels for e.g. shadows.
This was done with the help of several scripts, I dump them here to
easily find them later:
awk '/#ifdef/ { print "#cmakedefine01 "$2 }' AK/Debug.h.in
for debug_macro in $(awk '/#ifdef/ { print $2 }' AK/Debug.h.in)
do
find . \( -name '*.cpp' -o -name '*.h' -o -name '*.in' \) -not -path './Toolchain/*' -not -path './Build/*' -exec sed -i -E 's/#ifdef '$debug_macro'/#if '$debug_macro'/' {} \;
done
# Remember to remove WRAPPER_GERNERATOR_DEBUG from the list.
awk '/#cmake/ { print "set("$2" ON)" }' AK/Debug.h.in
blit() calls draw_scaled_bitmap() behind the scenes in scaled contexts,
and that doesn't like src_rect to be outside of the source bitmap's
bounds. Implicitly clip with the source rect, like the non-scaled
codepath already does.
Fixes#5017 even more.