Add dedicated internal types for Int64 and UnsignedInt64. This makes it
a bit more straightforward to work with 64-bit numbers (instead of just
implicitly storing them as doubles.)
With this patch, you can now assign the same GTextDocument to multiple
GTextEditor widgets via GTextEditor::set_document().
The editors have independent cursors and selection, but all changes
are shared, and immediately propagate to all editors.
This is very unoptimized and will do lots of unnecessary invalidation,
especially line re-wrapping and repainting over and over again.
This patch decouples GTextDocument and GTextDocumentLine from the line
wrapping functionality of GTextEditor.
This should basically make it possible to have multiple GTextEditors
editing the same GTextDocument. Of course, that will require a bit more
work since there's no paint invalidation yet.
The idea here is to decouple the document from the editor widget so you
could have multiple editors being views onto the same document.
This doesn't work yet, since the document and editor are coupled in
various ways still (including a per-line back-pointer to the editor.)
This makes double-clicking on a C++ token in HackStudio select the
whole token, which is pretty nice. It's not perfect in all cases,
but a lot nicer than just expanding until we hit whitespace. :^)
This makes the backspace erase backwards until the next soft tab stop.
We currently always use 4 as the soft tab width, but I suppose we could
make it configurable at some point. :^)
Instead of only doing a relayout in the widget you're invalidating,
we now do a recursive top-down relayout so everything gets updated.
This fixes invalid results after updating a preferred size in some
situations with nested layouts.
It's now possible to give GTextEditor a vector of Span objects.
Spans currently tell the editor which color to use for each character
in the span. This can be used to implement syntax highlighting :^)
Added a window creation callback to GApplication that gets called
by GWindow which will reset any pending exit request in the
CEventLoop.
This is to prevent a bug which prevents your application from
starting up if you had a message box or other dialog before
showing your main application form. The bug was triggered by
there being no more visible windows which was triggering a
premature quit().
When using the bounded string operations (e.g. snprintf), the null
terminator was always being written even if there was no space for
it (or indeed any valid buffer at all)
This overwriting caused segmentation faults and memory corruption
This could happen if a child was added to a GTabWidget before the
GTabWidget had its first layout.
Also add an assertion to catch this in GWidget::set_relative_rect()
since it was not immediately obvious what was happening.
Thread::make_userspace_stack_for_main_thread is only ever called from
Process::do_exec, after all the fun ELF loading and TSS setup has
occured.
The calculations in there that check if the combined argv + envp
size will exceed the default stack size are not used in the rest of
the stack setup. So, it should be safe to move this to the beginning
of do_exec and bail early with -E2BIG, just like the man pages say.
Additionally, advertise this limit in limits.h to be a good POSIX.1
citizen. :)
Instead of quitting the application immediately when the pty gives an
EOF, fire an on_command_exit hook so the TerminalWidget client can
decide for himself what to do.
Instead, have TerminalWidget provide an on_title_change hook.
This allows embedders to decide for themselves what to do if we receive
a "set terminal title" escape sequence.
When embedding a TerminalWidget, you might not want it to automatically
update its own size policy based on the exact terminal buffer size.
This behavior is now passed as a flag to the TerminalWidget constructor
which makes it behave nicely both inside HackStudio and in Terminal.
TerminalWidget was relying on the "window became active/inactive"
events from WindowServer to update its own internal focus state.
Unfortunately those events are only sent to the window's main widget,
so this was not working when the TerminalWidget was embedded deeper in
a widget tree.
This patch hooks the focusin and focusout events and uses those to
set the focus state when received. This makes TerminalWidget behave
nicely in both configurations. This design is kind of a workaround for
this awkward focus architecture and we should figure out something
better in the long term.
It turns out that other engines also prefer <h1 id=x> over <a name=x>.
So we can just use get_element_by_id() directly without worrying about
the type of element we find.
It turns out that other engines prefer <a id> over <a name> when
deciding which anchor element to jump to.
This patch aligns LibHTML's behavior with WebKit and Gecko.
Thanks to "/cam 2" for bringing this up. :^)
These will be useful for implementing various things. They don't do any
caching at the moment, but that might become valuable in the future.
To facilitate this change, I also made it possible to abort a tree walk
with for_each_in_subtree() by returning IterationDecision::Break from
the callback.
After the splitting-into-lines pass, remove any trailing whitespace
from all of a block's line boxes.
This improves the appearance of text-align: justify/right :^)
In order for this to work nicely, I made the line box classes use float
instead of int for its geometry information.
Justification works by distributing all of the whitespace on the line
(including the trailing whitespace before the line break) evenly across
the spaces in-between words.
We should probably use floating point (or maybe fixed point?) for all
the layout metrics stuff. But one thing at a time. :^)
Remove the Document pointer from HtmlView and always get to it through
the main Frame instead.
The idea here is to move towards HtmlView being higher-level than the
DOM stuff (as much as possible and practical.)
This patch implements basic support for <a href="#foo"> fragment links.
To figure out where we actually want to scroll to, we have to do
something different based on the layout node's box type. So if it's a
regular LayoutBox we can just use the LayoutBox::position().
However, if it's an inline layout node, we use the position of the
first line box fragment in the containing block contributed by this
layout node or one of its descendants.
Basically the same exact fix as I did for replaced elements. There's no
point in inserting a line break at the start of a line if all you're
trying to achieve is make more horizontal space for something.