Instead of only looking in the focused widget, we now also look in the
ancestor chain of that widget for any ancestor with a registered action
for the given shortcut.
This makes it possible for parent widgets to capture action activations
while one of their children is focused.
This is required for template literals - we're not quite there yet, but at
least the parser can now tell us when this token is encountered -
currently this yields "Unexpected token Invalid". Not really helpful.
The character is a "backtick", but as we already have
TokenType::{StringLiteral,RegexLiteral} this seemed like a fitting name.
This also enables syntax highlighting for template literals in the js
REPL and LibGUI's JSSyntaxHighlighter.
The original implementation only sent out notifications when there was
something being drawn on screen. If nothing was going on, we'd get too
lazy and just not notify display links.
This obviously break requestAnimationFrame(), so now we just drive the
DisplayLinks at 60 fps no matter what. :^)
This patch adds GUI::Action::create_checkable() helpers that work just
like the existing create() helpers, but the actions become checkable(!)
Clients are no longer required to manage the checked state of their
actions manually, but instead they will be checked/unchecked as needed
by GUI::Action itself before the activation hook is fired.
This little tweak fixes the issue where the scrolling speeds up
significantly if the user wiggles their cursor. Just something obvious
I spotted while watching the video :^)
Previously, TextEditor processed the Select all command directly on the
keydown event handler. For this reason, WindowManager would not process
it as an action for the focused control and an action with the same
keyboard shortcut from the parent could override the TextEditor's one
even when it is focused.
For instance, when pressing Ctrl+A on the FileManager's path bar, all
files were selected instead, which is not the expected behavior.
Now the Select all command is an actual action on TextEditor, so that
WindowManager can process it correctly before any other actions. I also
added an icon for it!
If you select some text and drag the cursor outside the widget on the
left hand side, we would previously suddenly snap the selection cursor
to the end of the line instead of keeping it at the start of the line
as you would expect. This patch fixes that. :^)
If you start selecting text and move the cursor outside the TextEditor
widget area without letting go of the mouse button, we will now keep
scrolling a little bit every 100ms.
Previously, drag and drop would only work when dragging between node
items on a DirectoryView. This commit makes it possible to drag files to
the empty area of the DirectoryView and copy files more easily between
windows.
This API is used to open a URL in whatever way the desktop system feels
is best. If you give it a file:// URL, it will try to work out a good
application to open the URL with. For all other protocols, it will open
a Browser instance. :^)
For some reason this was trying to access the Palette of the parent
widget which is obviously not going to work if the ItemView itself is
the main widget in its window.
If the area or size_in_bytes calculation for a Gfx::Bitmap would
overflow, we now refuse to create such a bitmap and return nullptr.
Thanks to @itamar8910 for finding this! :^)
This is really just a workaround to keep SystemMonitor's process table
working right wrt selection retention during resorts (while also doing
full index invalidation on things like ProfileViewer inversion.)
It's starting to feel like the model abstraction is not super great
and we'll need a better approach if we want to actually build some more
dynamic functionality into our views.
ColorInput is a new GUI component for selecting color using ColorPicker dialog.
It is simplify usage of ColorPicker dialog and more elegant view of current selected color.
This is a stop-gap patch solution for the annoying problem of models
being bad at updating. At least the process table will retain your
selection in SystemMonitor now.
This allows us to construct menus in a more natural way:
auto& file_menu = menubar->add_menu("File");
file_menu.add_action(...);
Instead of the old way:
auto file_menu = GUI::Menu::construct();
file_menu->add_action(...);
menubar->add_menu(file_menu);