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.
Previously, if a drag operation was aborted by pressing the escape key
(handled by WindowServer), the drag would immediately restart if you
moved the mouse cursor before releasing the mouse button.
Gutter -- a space left of the text, before the ruler -- is not a part of
the ruler, nor should it be treated as such. This commit implements
gutter handling in LibGUI::TextEditor as part of mild cleaning up of the
gutter handling (breakpoint icons) in HackStudio's Editor.
This commit also enables separate theming of the gutter.
The autocomplete box closes on its own when the user tries to hover
over it because text_editor consideres hovering over the box to be
a leave_event. This commit stops that from happening.
Let clients manage their own window ID's. If you try to create a new
window with an existing ID, WindowServer will simply disconnect you
for misbehaving.
This removes the need for window creation to be synchronous, which
means that most GUI applications can now batch their entire GUI
initialization sequence without having to block waiting for responses.
It's prone to finding "technically uninitialized but can never happen"
cases, particularly in Optional<T> and Variant<Ts...>.
The general case seems to be that it cannot infer the dependency
between Variant's index (or Optional's boolean state) and a particular
alternative (or Optional's buffer) being untouched.
So it can flag cases like this:
```c++
if (index == StaticIndexForF)
new (new_buffer) F(move(*bit_cast<F*>(old_buffer)));
```
The code in that branch can _technically_ make a partially initialized
`F`, but that path can never be taken since the buffer holding an
object of type `F` and the condition being true are correlated, and so
will never be taken _unless_ the buffer holds an object of type `F`.
This commit also removed the various 'diagnostic ignored' pragmas used
to work around this warning, as they no longer do anything.
This fixes#7946
Previously, TextEditor::write_to_file() would not mark its document
as unmodified if the file size was 0. This caused a desync in the
Text Editor app between the window's is_modified state and the
TextEditor's. It's already noted in the comments of the app's
save action code that propagating the modified state automatically
would be good, and it would solve issues like this, but I'm not yet
familiar enough with the code to try a change like that.
When the cursor is clicked outside of the slider knob,
the current behavior is that it will step up or down by the
Slider page step amount.
This commit adds an option to jump the slider knob
directly to the where the mouse cursor is on mouse down events.
This behavior is disabled by default. It must be enabled with
`Slider::set_jump_to_cursor()`.
Jump to cursor is enabled in SoundPlayer since most music players
have this behavior.
And use them to highlight javascript in HTML source.
This commit also changes how TextDocumentSpan::data is interpreted,
as it used to be an opaque pointer, but everyone stuffed an enum value
inside it, which made the values not unique to each highlighter;
that field is now a u64 serial id.
The syntax highlighters don't need to change their ways of stuffing
token types into that field, but a highlighter that calls another
nested highlighter needs to register the nested types for use with
token pairs.
Previously, AK::Function would accept _any_ callable type, and try to
call it when called, first with the given set of arguments, then with
zero arguments, and if all of those failed, it would simply not call the
function and **return a value-constructed Out type**.
This lead to many, many, many hard to debug situations when someone
forgot a `const` in their lambda argument types, and many cases of
people taking zero arguments in their lambdas to ignore them.
This commit reworks the Function interface to not include any such
surprising behaviour, if your function instance is not callable with
the declared argument set of the Function, it can simply not be
assigned to that Function instance, end of story.
When clicking on the TreeView in profiler without selecting a node and
then pressing up or pgup, cursor_index was in an invalid state. Instead
select the first node in the index.
This changes the INI and GML lexers to conform to the now-fixed
rendering of syntax highlighting spans in GUI::TextEditor.
The other user of GMLToken::m_end, GMLAutocompleteProvider, has been
modified to take into account that end position columns have been
incremented by one.
This fixes an off-by-one error in TextEditor's rendering of the syntax
highlighting as generated by Syntax::Highlighter and its subclasses.
Before, a single character span was e.g. (0-3) to (0-3), but this was
considered invalid by GUI::TextRange. Now, a single character span would
be e.g. (0-3) to (0-4).
This fix requires all Syntax::Highlighter subclasses to be adjusted, as
they all relied on the previous implementation. This will then also fix
a bug where single-character HTML tags wouldn't be highlighted.
Previously when using icon_for_path(), without specifying t_mode, on an
anonymous file it would return an empty Icon causing problems down the
line. Instead return the s_file_icon when stat fails.
This replaces ctype.h with CharacterType.h everywhere I could find
issues with narrowing conversions. While using it will probably make
sense almost everywhere in the future, the most critical places should
have been addressed.
Previous to this commit, if a `Window` wanted to set its width or height
greater than `INT16_MAX` (32768), both the application owning the Window
and the WindowServer would crash.
The root of this issue is that `size_would_overflow` check in `Bitmap`
has checks for `INT16_MAX`, and `Window.cpp:786` that is called by
`Gfx::Bitmap::create_with_anonymous_buffer` would get null back, then
causing a chain of events resulting in crashes.
Crashes can still occur but with `VERIFY` and `did_misbehave` the
causes of the crash can be more readily identified.
When setting a Widget->set_visible(false), if that Widget->has_focus()
it will continue to have focus, even though it's not visible to the user
anymore.
Now calling Widget->set_visible(false) will remove focus from the Widget
if it had focus, and the Window will give focus back to the Widget
that had it previously, if there was one.
This adds support for shift+return key combo in single line TextEditor
fields. Used in this case for searching backwards/forwards in the
Terminal find window.
Previously we didn't check that the selection's row index is in a valid
range before attempting to access its data via the model.
This could cause an out-of-bounds access to the model's Vector of
suggestions.
I think this should fix#7404, but I can't verify it does because
I wasn't able to reproduce it on my machine.
The index of the tree column will not change while painting.
Neither will the number of columsn. So avoid a whole bunch of virtual
function calls by caching these two values at the start of painting.
This adds an implementation for the Home, End, Page Up and Page Down
cursor movements for TreeView.
Also, the Up and Down movement implementations are replaced by a more
efficient traversal mechanism: whereas the old code would walk over all
visible nodes every time, the new code only evaluates relevant sibling
and parent indices.
Previously, the layout algorithm preferred to give every item an equally
sized slice of the remaining space. This meant that not the entire area
was used when the remaining size did not divide evenly by the number of
items. This caused, for example, the ResizeCorner in HexEditor to be a
couple of pixels left of the actual corner for some sizes of the window.
Now, the remaining pixels are distributed on a first come, first served
basis. However, only one pixel is distributed at a time. This means
items towards the left might me a pixel larger than their siblings
towards the right.
This moves the calculation of selected words that was originally
in the TextEditor application to TextEditor in LibGUI.
This allows all applications with text editors to get
this number without having to calculating it themselves.