Age | Commit message (Collapse) | Author |
|
|
|
Adds new filetype icons for forms and project files and a new root
icon for HackStudio's project tree.
|
|
|
|
The implementation in LibC did a timestamp->day-of-week conversion
which looks like a valuable thing to have. But we only need it in
time_to_tm, where we already computed year/month/day -- so let's
consolidate on the day_of_week function in DateTime (which is
getting extracted to AK).
|
|
|
|
|
|
|
|
|
|
Make sure the expression is evaluated as time_t so that it does
the right thing after 2037, and factor things so that the constants
look less magical.
|
|
The JS tests pointed out that the implementation in DateTime
had an off-by-one in the month when doing the leap year check,
so this change fixes that bug.
|
|
|
|
I believe the implementation in RTC.cpp had an off-by-one
in the year passed to is_leap_year(). If that's true, then this
fixes that too.
|
|
|
|
The fact that a `MarkedValueList` had to be created was just annoying,
so here's an alternative.
This patchset also removes some (now) unneeded MarkedValueList.h includes.
|
|
Previously you had to drag all the way to the end of a glyph to select
it; now you just need to drag past the center. Also fixes #2959.
|
|
We can't use a HashMap with a small key that doesn't guarantee
collisions. Change it to a HashTable instead.
Fixes #3254
|
|
We need to hold the memory manager lock so nobody else can modify
these lists while we're iterating them.
|
|
Specifically:
- post-increment actually implemented pre-increment
- helper-templates that provided operator{+,-,*,/}() couldn't possibly work,
because the interface of add (etc) were incompatible (not taking a Checked<>,
and returning void)
|
|
|
|
The view needs to recompute the scrollable content size whenever this
happens, so let's always notify it. Previously we were only doing this
when resizing columns with interactively (not programmatically.)
|
|
What you install with this API is a delegate that manages painting of
all the items in a specific column, so let's make the API reflect that.
|
|
This patch introduces the HeaderView class, which is a widget that
implements the column headers of TableView and TreeView.
This greatly simplifies event management in the view implementations
and also makes it much easier to eventually implement row headers.
|
|
It wasn't using any of the Frame features, so I'm not sure what the
idea here was.
|
|
This way we don't draw the frame border underneath our children. :^)
|
|
This patch adds Widget::children_clip_rect() which can be overridden
to tighten clipping of a widget's children. The default implementation
simply returns Widget::rect().
|
|
|
|
A Widget can now have a focus proxy widget. Questions about focus are
redirected to the proxy if present. This is useful if a widget could
logically get focus, but wants one of its child widgets to actually
handle it.
|
|
serenity/Build/Root/usr/include/sys/socket.h:93:26: error: 'sockaddr_un' undeclared here (not in a function)
93 | char data[sizeof(sockaddr_un)];
| ^~~~~~~~~~~
make[2]: *** [<builtin>: bss_fd.o] Error 1
|
|
|
|
|
|
|
|
Also clamp mouse events to frame rect when dragging outside of the color
field area.
Store hue separately from color, to prevent pure white resetting the hue
back to 0.
|
|
|
|
|
|
|
|
|
|
|
|
With this, if clicking the gutter until the scrubber's below the
mouse and then releasing the mouse, the scrubber is correctly
highlighted after releasing the mouse.
|
|
While left-mouse is pressed on any component (arrows, gutter, scrubber),
don't draw hover states for components other than the pressed component.
For example, while clicking the arrow-down button and then dragging
around, the arrow-up button and the scrubber now aren't highlighted.
This also means that during a gutter drag session, the scrubber
isn't highlighted while it's under the mouse cursor. That makes
sense, since we get the gutter drag behavior, not the scrubber
drag behavior, in this case.
The highlight is supposed to indicate "clickability", but if the
mouse is already down, they can't be clicked.
Now that I check for it, this seems to match the scrollbar behavior
on Windows.
|
|
And remove the now-redundant members m_scrubbing, m_scrubber_in_use,
and m_automatic_scrolling_kind.
This also made it clear that we weren't canceling the autoscroll
timer if the scrollbar got disabled while it was scrolling, so
this fixes that too.
|
|
The motivation for this change is twofold:
- Returning a JS::Value is misleading as one would expect it to carry
some meaningful information, like maybe the error object that's being
created, but in fact it is always empty. Supposedly to serve as a
shortcut for the common case of "throw and return empty value", but
that's just leading us to my second point.
- Inconsistent usage / coding style: as of this commit there are 114
uses of throw_exception() discarding its return value and 55 uses
directly returning the call result (in LibJS, not counting LibWeb);
with the first style often having a more explicit empty value (or
nullptr in some cases) return anyway.
One more line to always make the return value obvious is should be
worth it.
So now it's basically always these steps, which is already being used in
the majority of cases (as outlined above):
- Throw an exception. This mutates interpreter state by updating
m_exception and unwinding, but doesn't return anything.
- Let the caller explicitly return an empty value, nullptr or anything
else itself.
|
|
Note that m_hovered_component is only updated on mouse move, not while
just keeping left down. It's arguably wrong to update it on mouse move
while the mouse is down, I'll probably change things so that it doesn't
update there either.
The behavior on click-in-gutter-keep-left-down-then-move-mouse varies
a surprising amount between platforms. This implements the macOS
behavior where the scrubber follows the mouse direction while scrolling
by pages. (To be precise, it's the macOS behavior of Finder and Preview,
Safari has Windows's scrollbar behavior).
On Windows, the first click locks in the scroll direction and then
dragging the mouse off the scrubber in that direction makes the
scroll continue, but dragging it off the other direction has no effect.
I see no reason for that behavior.
|
|
Rather than disable and re-enable the timer, always keep it active
and make it do collision checks to decide if it should have an effect.
This is because set_automatic_scrolling_active(true) calls the
timeout callback immediately before starting the timer, and
when clicking the gutter this callback could disable the timer
again (if the first page scroll put the scrubber under the cursor).
Intead of making set_automatic_scrolling_active() work when it's
called reentrantly (which is easy: just swap the order of
on_automatic_scrolling_timer_fired() and timer->start() so that
on_automatic_scrolling_timer_fired() can immediately stop the
timer again, but it's confusing), make the timer check if it
should do anything.
This is keyed off m_last_mouse_position instead of
m_hovered_component because m_hovered_component is a visual state
and we arguably shouldn't modify it while the left mouse button
is down (as it indicated what part is activated on click).
|
|
|
|
...and use it in mousedown_event(), which allows putting in
stricter asserts.
|
|
|
|
Most callers of set_automatic_scrolling_active() also change
m_automatic_scrolling_kind, and it makes it possible to make timer
behavior dependent on the autoscroll kind later.
|
|
AutomaticScrollingKind
Also rename Decrement to DecrementButton and Increment to
IncrementButton.
|
|
It's slightly less code, and m_scrubber_in_use is now set correctly
when shift-clicking, keeping the mouse button down, and then
dragging the throbber.
The shift-click brings the scrubber under the cursor, and then
the scrubber_rect().contains() condition is true and both scrubber
drags and shift-click-drags are handled the same naturally.
|
|
Consider the following scenario:
if(condition)
FOO();
else
bar();
Suppose FOO is defined as follows:
#define FOO() { bar(); baz(); }
Then it expands to the following:
if(condition)
// Syntax error, we are not allowed to put a semicolon at the end.
{ bar(); baz(); };
else
bar();
If we define FOO as follows:
#define FOO() do { bar(); baz(); } while(false)
Then it expands to the following:
if(condition)
do { bar(); baz(); } while(false);
else
bar();
Which is correct.
|