Instead of using a scan code, which for scan code set 2 will not
represent the expected character mapping index, we could just use
another variable in the KeyEvent structure that correctly points to the
character index.
This change is mostly relevant to the KeyboardMapper application, and
also to the WindowServer code, as both handle KeyEvents and need to
use the character mapping index in various situations.
This commit un-deprecates DeprecatedString, and repurposes it as a byte
string.
As the null state has already been removed, there are no other
particularly hairy blockers in repurposing this type as a byte string
(what it _really_ is).
This commit is auto-generated:
$ xs=$(ack -l \bDeprecatedString\b\|deprecated_string AK Userland \
Meta Ports Ladybird Tests Kernel)
$ perl -pie 's/\bDeprecatedString\b/ByteString/g;
s/deprecated_string/byte_string/g' $xs
$ clang-format --style=file -i \
$(git diff --name-only | grep \.cpp\|\.h)
$ gn format $(git ls-files '*.gn' '*.gni')
The roll-up feature allows the user to set the window content to be
hidden, while retaining the window title bar visibility.
While in roll-up mode, the window height size is not changeable.
However, tiling the window or maximizing (as well as unmaximize) it will
instruct exiting the roll-up mode.
You can now add applications to Quick Launch via the context
menu option of their windows. Clicking it creates an event with the
stored PID of the process that created the window. The Taskbar receives
the event and tells the QuickLaunchWidget to add the PID, which then
gets the executable using /sys/kernel/processes. It also looks for an
AppFile using the name from the process object and if there is one, it
uses that, since it should contain a better formatted name.
The "Window" classes in LibGUI and WindowServer now store the PID of the
process that created the window. LibGUI's Window obtains the PID in the
constructor via getpid(), and passes it in Window::show() to
WindowServer via the create_window() IPC route. WindowServer then saves
it in its own Window class.
This allows us to find the process that created a window in order to add
process-specific actions to the window.
From what I can tell, this facility was added to WSWindow/GWindow in
2019 in 9b71307. I only found a single place in the codebase still using
this facility: `WindowServer::Menu::start_activation_animation()`. A
subtle fade-out animation that happens when a menu item is selected, and
the menu disappears.
I think our compositing facilities have improved enough to make this
facility redundant. The remaining use mentioned above was ported to just
directly blit the fade-out animation instead of requesting it from
WindowServer.
Previously, calling `.right()` on a `Gfx::Rect` would return the last
column's coordinate still inside the rectangle, or `left + width - 1`.
This is called 'endpoint inclusive' and does not make a lot of sense for
`Gfx::Rect<float>` where a rectangle of width 5 at position (0, 0) would
return 4 as its right side. This same problem exists for `.bottom()`.
This changes `Gfx::Rect` to be endpoint exclusive, which gives us the
nice property that `width = right - left` and `height = bottom - top`.
It enables us to treat `Gfx::Rect<int>` and `Gfx::Rect<float>` exactly
the same.
All users of `Gfx::Rect` have been updated accordingly.
Previously it was possible for a window to register as a parentless
blocking modal then add itself to a stealable parent's modal chain,
bypassing a mode misbehavior check in create_window()
Also relaxes reciprocity for blockers with the same parent. This
scenario is usually created by simultaneous MessageBoxes. It's not
an ideal UX to cascade these, but there's no need to crash over it.
Resolves#18624
Switching to and from fullscreen produces a behaviour where window
content too big in relation to window size.
This patch fixes sent resize event to contain current
window size.
Some keymaps will bind key presses with the alt modifier to characters
other than the unmodified one, in which case you couldn't activate the
alt shortcuts in the menu bar before.
We now ask the current keymap for the code point that is mapped to the
pressed (unmodified) key instead.
The old `GUI::Window` resizing behavior created a new backing store for
each resize event (i.e. every visible window size). This caused a lot of
trashing and on my machine, caused up to 25% of CPU time spent in
creating new backing stores.
The new behavior is a bit more sensible:
* If the window size is shrinking, the backing store is already large
enough to contain the entire window - so we don't create a new one.
* If the window size is growing, as soon as the backing store can no
longer contain the window, it is inflated with a large margin (of an
arbitrary chosen 64 pixels) in both directions to accommodate some
leeway in resizing before an even larger backing store is required.
* When the user stops resizing the window, the backing store is
resized to the exact dimensions of the window.
For me, this brings the CPU time for creating backing stores down to 0%.
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
This was causing a slight delay when opening ComboBox ListViews.
As an easy first optimization, don't bother computing this at all
for frameless windows and those not type Normal.
and the CaptureInput mode. They are a source of unneeded complexity
in WindowServer and have proven prone to regressions, so this patch
replaces them with a simple input preemption scheme using Popups.
Popup windows now have ergonomics similar to menus: When open,
a popup preempts all mouse and key events for the entire window
stack; however, they are fragile and will close after WindowServer
swallows the first event outside them. This is similar to how combo
box windows and popups work in the classic Windows DE and has the
added benefit of letting the user click anywhere to dismiss a popup
without having to worry about unwanted interactions with other
widgets.
with WindowInput{Preempted,Restored} Events and allow Widgets to save
the state of their focus preemption. As of now, only Popups will
preempt input and trigger these events.
LibWeb's Window object will need to know the OS-level position and size
of the GUI::Window for e.g. screenX, screenY, outerWidth, outerHeight.
It will also need to know about changes to that data.
This was too restrictive and there are already UI elements that rely
on this behavior. Now Blocking modals will preempt interaction with
all windows in their modal chain except those descending from them.
Fixes crashing in FilePicker when permission is denied.
This exception is necessary for ComboBoxes used in some blocking
Dialogs. CaptureInput is now the only mode which can spawn from
a blocking modal and it won't accept any children of its own.
This was a cludge for ComboBox ListView windows when they were first
implemented. The behavior is no longer needed and not very ergonomic
when moving Normal windows around.
But do allow them to remain minimizable by a parent. This is a nice
ergonomics fix to allow a parent window to quickly minimize and
restore all its modal children.
And apply modal effects on move_to_front_and_make_active()
Instead of building a vector of windows every time we want to
loop over a group of related modals, simply recurse through
their ancestory. This lineage is now called a modal chain. Modal
chains begin at the first modeless parent, and a new chain
starts at every modeless child. This lets apps spawn child windows
independent of the main window's modal effects, restore state,
and workspace, yet still remain descendants.
Looping through a modal chain is recursive and includes the
modeless window which begins it.
with the CaptureInput WindowMode. This mode will serve the same
function as accessories: redirecting input while allowing parent
windows to remain active.
Previously, Windows only understood blocking modality: Windows were
either modal, i.e., in a blocking state, or not. Windows could also
be set as Accessories or ToolWindows, attributes which technically
applied modes to their parents but were implemented ad hoc. This patch
redefines these modal effects as WindowModes and sets up some helpers.
This will let us simplify a lot of modal logic in the upcoming patches
and make it easier to build new modal effects in the future.
Windows can now set 1 of 5 modes before reification:
-Modeless: No modal effect; begins a new modal chain
-Passive: Window joins its modal chain but has no effect
-RenderAbove: Window renders above its parent
-CaptureInput: Window captures the active input role from its parent
-Blocking: Window blocks all interaction with its modal chain
States like fullscreen and tiling are dynamic and don't alter behavior
in modal chains, so they aren't included.
Superceded by to_floating_cursor_position() as a more accurate way
to reposition windows on untile. Effectively made set_size_around()
dead code, so the remnants can be removed.
Positioning windows outside visible coordinates is valid if sometimes
curious behavior, but it shouldn't be considered misbehavior by default.
There are multiple ways to recover windows with obscured title bars,
and this function papers over actual resize bugs and is no longer
needed to normalize window size, so let's remove it for now.
And remove unnecessary workarounds to the old limit of {50, 50} and
the cautious but arbitrary limit of {1, 1} for other WindowTypes.
Null rects are already the default when calculating minimum window
size and are the least restrictive but valid value.
Also returns early during minimum size calculations for frameless
windows, and verifies against negative minimum sizes and failure to
disable widget min size before setting a minimum window size. Layout
automatically overrides this setting each relayout otherwise.
Menu and Window animations can now be disabled and the geometry
overlay made conditional. Shadow options are dependent on the
current theme actually supplying bitmaps, but they provide a fast
way to toggle those that do without having to edit theme files.
Each of these strings would previously rely on StringView's char const*
constructor overload, which would call __builtin_strlen on the string.
Since we now have operator ""sv, we can replace these with much simpler
versions. This opens the door to being able to remove
StringView(char const*).
No functional changes.
This commit has no behavior changes.
In particular, this does not fix any of the wrong uses of the previous
default parameter (which used to be 'false', meaning "only replace the
first occurence in the string"). It simply replaces the default uses by
String::replace(..., ReplaceMode::FirstOnly), leaving them incorrect.
Previously, GUI::Window::is_maximized() had to make a synchronous IPC
request to WindowServer in order to find out if the window was indeed
maximized.
This patch removes the need for synchronous IPC by instead pushing the
maximization state to clients when it changes.
The motivation for this change was that GUI::Statusbar was checking
if the containing window was maximized in its resize_event(), causing
all windows with a statusbar to block on sync IPC *during* resize.
Browser would typically block for ~15 milliseconds here every time
on my machine, continuously during live resize.
This is useful, for instance, in games in which you can switch held
items using the scroll wheel. In order to implement this, they
previously would have to either add a hard-coded division by 4, or look
up your mouse settings to adjust correctly.
This commit adds an MouseEvent.wheel_raw_delta_x() and
MouseEvent.wheel_raw_delta_y().
`static const` variables can be computed and initialized at run-time
during initialization or the first time a function is called. Change
them to `static constexpr` to ensure they are computed at
compile-time.
This allows some removal of `strlen` because the length of the
`StringView` can be used which is pre-computed at compile-time.