This patch makes it possible to live-edit remote object properties by
simply double clicking on them in the property table view.
This is pretty neat! :^)
Previously the focused widget would only get cleared on replacement or
on destruction (being a WeakPtr and all.) This could lead to window
dispatching events to a focused widget after it had been removed from
the window's widget tree.
The same issue existed for the hovered widget, etc. So this patch
makes sure that we eagerly clear the various widget pointers in Window
immediately when they are removed from the window's widget tree.
This patch adds a magenta rectangle around the currently inspected
widget. This allows you to browse an app's widget tree somewhat
visually using the Inspector. :^)
Add a SetInspectedObject call that tells us which Core::Object a remote
client is currently looking it. Objects get notified when they gain
their first inspector, and when they lose their last one.
Now that add() returns a WidgetType&, we can't rely on the parent of a
GUI::Dialog to still keep it alive after exec() returns. This happens
because exec() will call remove_from_parent() on itself before
returning.
And so we go back to the old idiom for creating a GUI::Dialog centered
above a specific window. Just call GUI::Dialog::construct(), passing
the "parent" window as the last parameter.
Since the returned object is now owned by the callee object, we can
simply vend a ChildType&. This allows us to use "." instead of "->"
at the call site, which is quite nice. :^)
This patch adds two new API's:
- WidgetType& GUI::Window::set_main_widget<WidgetType>();
This creates a new main widget for a window, assigns it, and returns
it to you as a WidgetType&.
- LayoutType& GUI::Widget::set_layout<LayoutType>();
Same basic idea, creates a new layout, assigns it, and returns it to
you as a LayoutType&.
Avoid creating SingleIndexes in case of byte ranges. This, boosts
the performance significantly in case a byte range is too big(e.g 666-123123).
Also, claim copyright over this mess since I am the one responsible for it.
This is a complete fix of clock_nanosleep, because the thread holds the
process lock again when returning from sleep()/sleep_until().
Therefore, no further concurrent invalidation can occur.
This adds a test for the race condition in clock_nanosleep.
The crux is that clock_nanosleep verifies that the output buffer
is writable *before* sleeping, and writes to it *after* sleeping.
In the meantime, a concurrent thread can make the output buffer
unwritable, e.g. by deallocating it.
This testcase is needlessly complex because pthread_kill is
not implemented yet. I tried to keep it as simple as possible.
Here is the relevant part of dmesg:
[nanosleep-race-outbuf-munmap(22:22)]: Unblock nanosleep-race-outbuf-munmap(20:20) due to signal
nanosleep-race-outbuf-munmap(20:20) Unrecoverable page fault, write to address 0x02130016
CRASH: Page Fault. Process: nanosleep-race-outbuf-munmap(20)
[nanosleep-race-outbuf-munmap(20:20)]: 0xc01160ff memcpy +44
[nanosleep-race-outbuf-munmap(20:20)]: 0xc014de64 Kernel::Process::crash(int, unsigned int) +782
[nanosleep-race-outbuf-munmap(20:20)]: 0xc01191b5 illegal_instruction_handler +0
[nanosleep-race-outbuf-munmap(20:20)]: 0xc011965b page_fault_handler +649
[nanosleep-race-outbuf-munmap(20:20)]: 0xc0117233 page_fault_asm_entry +22
[nanosleep-race-outbuf-munmap(20:20)]: 0xc011616b copy_to_user +102
[nanosleep-race-outbuf-munmap(20:20)]: 0xc015911f Kernel::Process::sys(Kernel::Syscall::SC_clock_nanosleep_params const*) +457
[nanosleep-race-outbuf-munmap(20:20)]: 0xc015daad syscall_handler +1130
[nanosleep-race-outbuf-munmap(20:20)]: 0xc015d597 syscall_asm_entry +29
[nanosleep-race-outbuf-munmap(20:20)]: 0x08048437 main +146
[nanosleep-race-outbuf-munmap(20:20)]: 0x08048573 _start +94
Most importantly, note that it crashes *inside*
Kernel::Process::sys.
Instead, the correct behavior is to return -EFAULT.
The selected option was stored in a captured stack variable which was
long gone by the time we looked at it, so this dialog didn't really
behave the way you'd expect. Put it in a member instead. :^)
Now it actually defaults to "a < b" comparison, instead of forcing you
to provide a trivial less-than comparator. Also you can pass in any
collection type that has .begin() and .end() and we'll sort it for you.
We were going from "new JSON format" => "old JSON format" => Event.
This made loading longer profiles unnecessarily slow. It's still pretty
slow, and we should... profile it! :^)