If you drag-select a slice of the profile off of the side of the
Profiler window, the profiler will try to render a negative start time,
which will overflow. This commit fixes that bug by clamping timestamps
to the start/end of the profile before rendering.
For some reason I don't yet understand, building the kernel with -O2
produces a way-too-large kernel on some people's systems.
Since there are some really nice performance benefits from -O2 in
userspace, let's do a compromise and build Userland with -O2 but
put Kernel back into the -Os box for now.
https://tc39.es/ecma262/#sec-properties-of-the-regexp-prototype-object
The RegExp prototype object:
- is an ordinary object.
- is not a RegExp instance and does not have a [[RegExpMatcher]]
internal slot or any of the other internal slots of RegExp instance
objects.
In other words: no need to have RegExpPrototype inherit from
RegExpObject (we weren't even calling its initialize()).
https://tc39.es/ecma262/#sec-properties-of-the-array-prototype-object
The Array prototype object: [...] is an Array exotic object and has the
internal methods specified for such objects.
NOTE: The Array prototype object is specified to be an Array exotic
object to ensure compatibility with ECMAScript code that was created
prior to the ECMAScript 2015 specification.
(...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.
The name-to-section lookup table was only used in a handful of places,
and none of them were calling it nearly enough to justify building
a cache for it in the first place. So let's get rid of it and reduce
startup time by a little bit. :^)
It's a lot faster to iterate the GNU hash tables if we don't have to
compute the length of every symbol name before rejecting it anyway while
comparing the first character. :^)
When performing a global symbol lookup, we were recomputing the symbol
hashes once for every dynamic object searched. The hash function was
at the very top of a profile (15%) of program startup.
With this change, the hash function is no longer visible among the top
stacks in the profile. :^)
This logging mode was unusable anyway since it spams way too much.
The dynamic loader is in a pretty good place now anyway, so I think
it's okay for us to drop some of the bring-up debug logging. :^)
Also, we have to be careful with dbgln_if(FOO_DEBUG, "{}", foo())
where foo() is something expensive, since it might get evaluated
even if !FOO_DEBUG.
Thanks to @trflynn89 for the neat implicit consteval ctor trick!
This allows us to basically slap `CheckedFormatString` on any
formatting function, and have its format argument checked at compiletime.
Note that there is a validator bug where it doesn't parse inner replaced
fields like `{:~>{}}` correctly (what should be 'left align with next
argument as size' is parsed as `{:~>{` following a literal closing
brace), so the compiletime checks are disabled on these temporarily by
forcing them to be StringViews.
This commit also removes the now unused `AK::StringLiteral` type (which
was introduced for use with NTTP strings).
We implement this by adding a BlockBox::is_scrollable() helper,
and then ignoring wheel events for non-scrollable boxes.
Thanks to FireFox317 for pointing this out! :^)
When files where placed in outside of the project root, they would
appear empty because the label in the tree would differ from the
actual file path relative to the root.
Fixes#5471.
This is rather crude, but you can now use the mouse wheel to scroll up
and down in block-level boxes with clipped overflowing content.
There's no limit to how far you can scroll in either direction, since
we don't yet track how much overflow there is. But it's a start. :^)
We now apply a paint-time clip to the padding rect of a BlockBox before
painting its inline-level children. This covers some of the behavior
we want from "overflow: hidden" etc but is far from a complete solution.
Handling crashes synchronously is finicky since we're modifying the
m_client_state struct while in a callback lambda owned by it.
Let's avoid all the footguns here by simply using deferred_invoke()
and handling the crash on next event loop iteration instead.
Also, only mark the menu bar item as opened if a menu was actually
opened through the menu bar.
These changes allow a menu to be used both in the menu bar as well
as a context menu.
Fixes#5469
Because re-evaluation of the hovered window may trigger sending a
MouseMove event to a window we should only wake it if the mouse
position actually has changed.
For example, navigating File Manager to a directory that contains a vaild BMP file that
uses a palette, this code would end up trying to create an indexed thumbnail.
However, Painter asserts that the thumbnail that we paint on is *not* indexed,
usually crashing File Manager.
Partially fixes#5299, as it now crashes somewhere else.
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.
This should really be a WindowProxy? but since we don't have anything
representing that concept yet, let's just expose the Window object
directly so document.defaultView.foo works. :^)
Most of the functions under FileUtils were removed, except those which
dealt with file deletion, as they spawned MessageBoxes for errors, as
such, those functions were written in terms of Core::File::remove.
FileManager, cp, mv, rm had some duplicated code, implementing basic
file management operations. This patch creates adds functions that try
to provide an interface suited for all these programs, but this patch
does not make them be used throughout the Userland.
They are added to Core::File following the example of functions such as
read_link/real_path_for.
Don't fire the on_terminal_size hook while we're in relayout.
This fixes the terminal window flopping around during interactive
resizing. (It was mostly noticeable if something else was hogging
the CPU at the same time.)
We didn't add buttons for certain window types or states when the
window was created, but when a window with a button changed its
state to where we would not have created the button, we didn't
remove the existing button.
These were forgotten in the last LibLine commit, any changes to m_buffer
not going through insert() and remove_at_index() should also be updating
these.
Fixes#5440.
Route the ScrollBar's wheel event to the ScrollableWidget so it can
handle it itself. This allows it to handle it consistently (e.g.
speed) when the cursor is hovering the scroll bars rather than the
widget's contents.
Fixes#5419
Let's use a stronger type than void* for this since we're talking
specifically about a virtual address and not necessarily a pointer
to something actually in memory (yet).
It was very confusing how these functions used the "undefined" state
of Symbol to signal lookup failure. Let's use Optional<T> to make things
a bit more understandable.
This patchset allows the editor to avoid redrawing the entire line when
the changes cause no unrecoverable style updates, and are at the end of
the line (this applies to most normal typing situations).
Cases that this does not resolve:
- When the cursor is not at the end of the buffer
- When a display refresh changes the styles on the already-drawn parts
of the line
- When the prompt has not yet been drawn, or has somehow changed
Fixes#5296.
Fixes hidable horizontal scrollbars remaining visible even after
collapsing their responsible nodes. Tree column width defaults to
column header width if wider than current content.
The C++ LanguageServer can now find the matching declaration for
variable names, function calls, struct/class types and properties.
When clicking on one of the above with Ctrl pressed, HackStudio will
ask the language server to find a matching declaration, and navigate
to the result in the Editor. :^)
AbstractView doesn't actually do anything with them anyway, but they
would get swallowed by the cursor logic and not bubble up the widget
parent chain.
This makes the shortcuts actually work since unparented actions are
considered application-global, and we disable application-global
shortcuts while a modal dialog (like FilePicker) is up. This is pretty
counter-intuitive so I think there's room for API improvement here
but let's at least make Alt+Up work in FilePicker for now. :^)
The overhead from spawning a new ImageDecoder for every decoding job is
way too large and causing other problems as well (#5421)
Let's keep the same decoder open and reuse it as long as it's working.
If the ImageDecoder service crashes while decoding an image for us,
we now recover gracefully and simply return null.
This shields the browser from bugs in our image decoders.
Instead of asserting that the peer responds successfully, this API
allows for the peer to die/crash/whatever happens on the other side
while handling a synchronous request.
This will be useful when using process separation to parse untrusted
data from the web.
There's a little bit of template magic involved here to make it work,
but this seems alright. Very cool! :^)
Co-authored-by: AnotherTest <ali.mpfard@gmail.com>
Much like AK::Result this carries either a DOM::DOMException or regular
return value and will be used by DOM functions for exceptions that
should be thrown.
This was needlessly expecting the first backtrace entry function name to
start with '__assertion_failed', which is no longer the case - it's now
something from libsystem.so. Let's just check whether we have an
'assertion' key in the coredump's metadata, just like we do for pledge
violations.
Tweak the PLT trampoline to avoid generating textrels in LibC.
This allows us to share all the LibC mappings, reducing per-process
memory consumption by ~200 KB. :^)
Patch originally by @nico.
To support this, I had to reorganize the "load_elf" function into two
passes. First we map all the dynamic objects, to get their symbols
into the global lookup table. Then we link all the dynamic objects.
So many read-only GOT's! :^)
The dynamic loader will now mark RELRO segments read-only after
performing relocations. This is pretty cool!
Note that this only applies to main executables so far,.
RELRO support for shared libraries will require some reorganizing
of the dynamic loader.
For a data segment that starts at a non-zero offset into a 4KB page and
crosses a 4KB page boundary, we were failing to pad the VM allocation,
which would cause the memcpy() to fail.
Make sure we round the segment bases down, and segment ends up, and the
issue goes away.
FooConstructor::construct() is no longer a dummy but now generates
either code to throw an exception (for interfaces without constructor)
or code to construct the wrapper and its impl object.
Constructor overloads are not currenly handled, but that's not something
we need right now anyway. Instead of regular create() this uses a new
static function create_with_global_object() and passes the WindowObject,
which may be needed - e.g. for XMLHttpRequest, which has an IDL and
JavaScript constructor with no arguments, but needs a DOM::Window in its
create().
Function::length() is computing the right function length based on its
parameters, but we never called it - instead the *function name length*
was being used, which is obviously wrong. How silly! :^)
By default, a Window has a minimum size of 50x50 - ComboBox lists aren't
always this tall. We now set the minimum height of the ComboBox Window
according to the height of three items, or the total height of all the
items in the list, whichever is smaller.
This means there is no longer any unpainted space in the list window
due to the shortfall between the ListBox widget and Window heights,
and the ComboBox list window always remains a comfortable height for
viewing. :^)
This is obviously a requirement for #5374, oops :^)
Also handle errors gracefully, opening a file that isn't PixelPaint JSON
would previously crash.
Closes#5388.
Tool windows are secondary windows with a smaller title bar. The sit on
the layer above normal windows, and cannot be minimized.
These are intended for complex yet non-modal interactions with the
content of a primary window, such as find/replace windows, property
windows, etc.
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.
POSIX explicitly allows providing nullptr's, and our __pthread_*() implementation
stores and calls the provided functions as-is, without checking for nullptr.
If the cursor Y position is < 0 in content coordinate space, we should
always map that to the first line of the file.
This fixes unexpected cursor behavior when dragging the selection above
the top of the document.
This removes some hard references to the toolchain, some unnecessary
uses of an external install command, and disables a -Werror flag (for
the time being) - only if run inside serenity.
With this, we can build and link the kernel :^)
This required a bit of rearchitecture, as pthread_atfork() required a
mutex, and duplicating a mutex impl for it was silly.
As such, this patch moves some standalone bits of pthread into LibC and
uses those to implement atfork().
It should be noted that for programs that don't use atfork(), this
mechanism only costs two atomic loads (as opposed to the normal mutex
lock+unlock) :^)
This implementation is pretty damn dumb, and probably has more bugs than
features.
But for the time being, it seems to work. however, we should definitely
replace it with a good implementation sometime very soon :^)
We need to first deliver the mouse event and possibly the double click
event and record these facts. Then, we need to iterate all global
tracking listeners and deliver the mouse event (but not the double
click event) to any such listener, unless they already had these
events delivered.
Fixes#4703
LookupServer can now itself server as a DNS server! To service DNS clients, it
uses the exact same lookup logic as it does for LibIPC clients. Namely, it will
synthesize records for data from /etc/hosts on its own (you can use this to
configure host names for your domain!), and forward other questions to
configured upstream DNS servers. On top of that, it implements its own caching,
so once a DNS resource record has been obtained from an upstream server,
LookupServer will cache it locally for faster future lookups.
The DNS server part of LookupServer is disabled by default, because it requires
you to run it as root (for it to bind to the port 53) and on boot, and we don't
want either by default. If you want to try it, modify SystemServer.ini like so:
[LookupServer]
Socket=/tmp/portal/lookup
SocketPermissions=666
Priority=low
KeepAlive=1
User=root
BootModes=text,graphical
and enable server mode in LookupServer.ini like so:
[DNS]
Nameservers=...
EnableServer=1
If in the future we implement socket takeover for IP sockets, these limitations
may be lifted.
Where it belongs, alongside the /etc/hosts check. The inner lookup() method is
really about talking to a specific DNS server.
Also, don't bail out on a empty name. An empty DNSName is actually '.' — a
single dot — aka the DNS root.
...just like we store m_lookup_cache, in other words.
This immediately lets us match on types: for instance we will now only resolve
1.0.0.127.in-addr.arpa to localhost if asked for type PTR, not for type A. In
the future, this could also let us have the same /etc/hosts name resolve
to *multiple* addresses.
DNSName can now take care of case conversion when comparing using traits.
It still intentionally doesn't implement operator ==; you have to explicitly
decide whether you want case-sensitive or case-insensitive comparison.
This change makes caches (and /etc/hosts) case-transparent: we will now match
domains if they're the same except for the case.
* DNSName knows how to randomize itself
* DNSPacket no longer constructs DNSQuestion instances, it receives an already
built DNSQuestion and just adds it to the list
* LookupServer::lookup() explicitly calls randomize_case() if it needs to
randomize the case.
This is a wrapper around a string representing a domain name (such as
"example.com"). It never has a trailing dot.
For now, this class doesn't do much except wrap the raw string. Subsequent
commits will add or move more functionality to it.