Instead of trying to update only the little bit that changes, let's
have a function that updates all the window menu items in one go.
It's just a couple of string and boolean assignment, and the real
cost is performing the subsequent menu redraw, which remains the same.
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.
Windows that are marked as modified will now have another (themable)
close button. This gives an additional visual clue that some action
will be required by the user before the window gets closed.
The default window-close-modified icon is an "X" with "..." underneath,
building on the established use of "..." in menus to signify that
additional user input will be required before an action is completed.
It's possible that the backing store hasn't been updated yet, so
when performing an alpha hit-test make sure the bitmap actually
contains it.
Fixes#6731
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 *
With this patch the window manager related functionality is split out
onto a new endpoint pair named WindowManagerServer/Client. This allows
window manager functionality to be potentially privilege separated in
the future. To this end, a new client named WMConnectionClient
is used to maintain a window manager connection. When a process
connects to the endpoint and greets the WindowServer as a window manager
(via Window::make_window_manager(int)), they're subscribed to the events
they requested via the WM event mask.
This patch also removes the hardcoding of the Taskbar WindowType to
receive WM events automatically. However, being a window manager still
requires having an active window, at the moment.
This is important when the window is maximized or tiled (which
recalculate_rect() will both check), as we otherwise create a gap above
the window frame (when hiding the menubar) or push the frame off the
screen (when showing the menubar).
We were writing to the currently hovered menu item index in a bunch
of places, which made it very confusing to follow how it changes.
Rename Menu::set_hovered_item() to set_hovered_index() and use it
in more places instead of manipulating m_hovered_item_index.
I hereby declare these to be full nouns that we don't split,
neither by space, nor by underscore:
- Breadcrumbbar
- Coolbar
- Menubar
- Progressbar
- Scrollbar
- Statusbar
- Taskbar
- Toolbar
This patch makes everything consistent by replacing every other variant
of these with the proper one. :^)
This patch adds support for opening menus via keyboard shortcuts.
Use an ampersand in a menu name to automatically create a keyboard
shortcut (Alt + the character following the ampersand.)
Menus with an Alt shortcut have a small underline under the shortcut
character for discoverability.
WindowServer now collects applet windows into an "applet area" which is
really just a window that a WM (window management) client can position
via IPC.
This is rather hackish, and I think we should come up with a better
architecture eventually, but this brings back the missing applets since
the global menu where they used to live is gone.
This patch begins the transition away from the global menu towards
per-window menus instead.
The global menu looks neat, but has always felt clunky, and there
are a number of usability problems with it, especially in programs
with multiple windows.
You can now call GUI::Window::set_menubar() to add a menubar to
your window. It will be specific to that one window only.
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.
Minimum window size can now be customised and set at runtime via the
SetWindowMinimumSize WindowServer message and the set_minimum_size
LibGUI::Window method. The default minimum size remains at 50x50.
Some behind-the-scenes mechanics had to be added to LibGUI::Window to
ensure that the minimum size is remembered if set before the window is
shown. WindowServer sends a resize event to the client if it requests a
size on create that's smaller than it's minimum size.
Merely moving a window shouldn't require re-rendering the window
frame anymore now that we cache the rendered frame in bitmaps. This
reduces CPU usage significantly when moving windows.
Button now can handle middle and right clicks.
Added 2 new handlers in button class: on_right_click for Right mouse
button and on_middle_click for middle mouse button.
Added functionality to vertically maximize window with middle mouse
click on the maximize window button.
Also added a way to vertically maximize window by resizing window
height-wise lower than the maximum window height.
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 commit:
- merges the two(!) places that defined independently the minimum size of a window.
- splits Window::normalize_rect(), which was originally just a function to apply
the minimum size requirement, and has taken on the additional job of nudging
windows back onto the desktop.
This inadvertantly fixes a crash that happens when a malicious program creates a
window of size (0, 0). Now, a window at [0,0 50x50] is created instead.
- Unmaximization/untiling had nearly but not quite code duplication;
this patch replaces the actual "regrabbing" logic with Rect::set_size_around.
- When undoing maximization/untiling, it used to be possible to to grab a window
"outside" of its frame, and thus drag it off the screen. This is no longer
possible. Fixes#4644.
- As a side effect, when untiling from the bottom/left/right, the regrab is now
a much smoother experience.
- Setting the resize aspect ratio while being tiled now untiles and umaximizes
the window, as these things are incompatible. Fixes an undocumented bug
(steps to reproduce: maximize, then set aspect ratio).
- When unmaximizing, spurious WindowLeft events were sent, because that path
didn't set hovered_window. Fixes an undocumented bug.
Since these things are interwoven, this is all a single commit.
Previously, SetWindowRect and SetWindowRect could supply basically arbitrary
x and y coordinates. This could happen either due to a malicious or malfunctioning
program, or even due to the auto-centering feature.
This patch also moves the 'normalization' code out of ClientConnection to Window,
where it belongs better.
Fixes#4135.
Fixes#5052.