Cover cases with interface implementation by delegation:
— Do not require two overridden symbols: both the delegate and the
explicit override can refer to the same interface method with a
default implementation.
— Fix subtyping check: delegates override members from the implemented
interface and its supertypes, not subtypes.
KTIJ-16228
GitOrigin-RevId: 93dde1f05141098c359e3e7d4f15a5a63083f44c
The class is already marked as internal.
No need to mention `terminal` in the event name because it is already a terminal group.
GitOrigin-RevId: 18fce5486c7085977e5fa433628b96c8f8dc1c89
Not sure how different versions of OS can affect the latency in our case, but who knows, let's see.
GitOrigin-RevId: b53b9ded5e9cfe7def9982b6f47c233dfa8b6535
Report it with the length of the collected text.
Also, had to run `TerminalContentChangesTrackerTest` with a project because it now contains FUS logging that requires application even in tests.
GitOrigin-RevId: 74dabd31c4bc28d80ff4cccd5ce9ca1bef32a727
Pass event time and id to the TerminalStarter. Implement the separate method for that in our override for that.
This way is more explicit and safe because it is not using the global state and matching by event object.
GitOrigin-RevId: ddbf4373bf6226c72bd8db3bc0d8b849d4ba3112
This approach leverages passing the `initTime` through all key event processing flow.
This way we little bit complicate the implementation, but remove the matching and global state hacks.
Also, this approach is harder to break during refactorings.
GitOrigin-RevId: 587088733902061074604109f6b3e9edfe245136
It will be used to measure the typing latency.
Also, I had to copy the `TerminalEventsHandler` interface to the frontend, because it was necessary to change the parameter types. Previously, we used the interface located in the shared part and common for Gen1 and Gen2.
GitOrigin-RevId: 6b8b0cccde598dc6cef9217232eb3c6725973f9a
Not sure that we need to track the latency when the terminal tab is hidden. Only user visible latency is important for us.
GitOrigin-RevId: 7cd859e90fe7494efd041e5c207b7993dd7f53ec
We need this `readTime` only locally on the backend and put it to the event object only for simplicity.
It is not a good design, but for now there is no suitable alternative. Ideally, we need to have the separate serializable DTO classes hierarchy for RPC.
Or switch to plain longs for measuring the time.
GitOrigin-RevId: f8e20acdfe0d856c73750711d1a14917fc9b5973
This implementation is more simple:
1. We track the last time of reading from the TTY.
2. We remember the time from step 1 when we text buffer is changed the first time. Here output accumulation session starts.
3. Once output is collected, we put the time from step 2 to the created `TerminalOutputUpdatedEvent` and reset it. Here output accumulation session ends.
4. Once we update the backend models with this event, we report the backend output latency and forward the event to the frontend.
GitOrigin-RevId: ed4e4920b46e5bdd7feb27fa7200e4858b629632
The initial wording was wrong: it does get called from
the terminal emulator thread sometimes,
on history overflow, when it's not the scrapping coroutine,
but the text buffer itself that initiates buffer collection.
GitOrigin-RevId: 75b99b8040bce96ce6bcb7be04d152ae1a286f80
There are two ways to fix this: either to imitate the real
scenario or by relaxing the state checks in the FUS activities
themselves. Otherwise tests fail because the FUS activity
is invoked in the wrong state (e.g., characters make their
way into the text buffer without being read first).
Let's fix it on the test side to avoid making changes
to production that are only needed for tests.
GitOrigin-RevId: 922f947f3c745de620112ec85b6e6932116c8a2b
The hardest part here is to understand when the received data
is actually displayed. The problem is that it may not be displayed
at all, for example, if the editor is hidden or scrolled away.
Using the hooks added to the editor, we can make an assumption:
if the editor is showing, and there was a repaint request,
then it's very likely to be repainted soon. In that case we wait
for the repaint before reporting the latency.
If there's no repaint request, then we report the latency immediately,
adding a boolean flag to the event to distinguish between the cases.
Because events are received and applied as whole,
there are no separate events for the first and last characters.
Instead, we report both character indices in one event.
So for two backend events we have one frontend event.
GitOrigin-RevId: df72687dc3ef31bece6eeaf7cd624dc18c462d6e
These are low-level hacky hooks that are needed to track
repaint requests and the following paint operations
to measure terminal frontend output latency.
With these hooks we can try to measure when the output
is actually painted.
GitOrigin-RevId: d308e50ebffd0705251c3d560e2979d9ff8a7f48
This is much harder than the input latency.
The output has a lifecycle of several phases.
The first phase: chars are read from the TTY connector.
This happens on the terminal emulator thread,
and we get a whole array of chars with a single timestamp.
The second phase: chars are processed by the emulator
at its own pace. This also happens on the terminal emulator
thread, so at least we can track this processing in a synchronous
manner. Some characters arrive into the text buffer,
but not all of them, as some control characters don't affect
the buffer. So we need to be careful to figure out
the char indices that actually made their way into the buffer.
The text buffer is updated under the text buffer lock,
but not all processing happens under this lock.
The third phase: the text buffer is collected (scrapped).
This doesn't happen on the terminal emulator thread,
but it happens under the same text buffer lock.
At this point an event is created, and we must carefully
match it to character indices.
The fourth phase: the event is collected by the frontend.
Finally we can measure the latency. But the latencies of the first
and the last characters can be different if they were read
at different times. So we report two latencies.
A dangerous part is that we need to ensure that events
are always collected. The current implementation guarantees
it. If during startup or shutdown an event or two are not collected,
it's not much of an issue as there's no global state here,
unlike the input latency measuring. The entire activity
is disposed along with the session.
Because, unlike input, it's possible to have parallel outputs,
every event is reported with the session ID.
GitOrigin-RevId: 50c2626163e03d905a4b62762276fda59b450452
This is a simple refactoring, needed to add more hooks
to the connector to implement output latency measuring.
GitOrigin-RevId: 6d3cfb6a679d7e72abdc5bd5e47b2cd5569c0ac7
This process is not single-threaded, but it involves only
one thread transfer: from the receiving coroutine
to the terminal thread, which uses an executor
that is never shut down, so it's pretty much a guarantee
that for every byte array there will be at least an attempt
to write it. Using this fact, we can store a byte array to activity
map and remove activities when the byte arrays are written.
Using a try-finally block there ensures that the activity is eventually
finished.
The activity ID is transferred along with the event,
to ensure that the same ID is used on the frontend and on the backend.
GitOrigin-RevId: 66587a5cca59053dab1e4bf2bee9bd098fe10637
The latency is measured from the Swing input event
to the moment when the resulting event is written to
the session's input channel, as that's where the frontend
part ends.
Measuring consists of two phases: Swing input event processing,
which is easy because it's single-threaded and is put in a try-finally
block; and terminal input event processing, which is trickier
because of the coroutines and the channel. Thankfully,
the channel provides API to ensure that a "resource" is always
closed: either the send operation fails, or the element is received,
or an "undelivered element" callback is fired. In order for it to work,
the channel also must be canceled (not just closed) eventually.
This allows us to keep an event-to-FUS-activity map and ensure
that it's always cleaned.
Input events are assigned global sequential IDs without corresponding
session IDs or anything like that because at the time the Swing event
arrives, it's not known yet which terminal session it belongs to,
or even if it belongs to any at all. So we just measure the time it takes
for an event to arrive to any session, if at all. It shouldn't be
an issue because it's impossible to have parallel input activities.
The latency is reported in microseconds, because it's very often
less than one millisecond.
GitOrigin-RevId: a31bdfe60d9e32fb16d0391d855a5e26011bf8fb
We have the class with the same name on the frontend. Let's mark this one as backend to make it easier to distinguish the files.
GitOrigin-RevId: 071b4375b72311c9ce5f6c64ed347e1eb3841c0b
The deprecated MarkdownFrontendService has been removed, along with the associated application service. Functionality previously handled by the service is now migrated to MarkdownLinkOpenerUtil.
GitOrigin-RevId: 80f8c549a4dd1614aff883b1010f197ce56b11bb
Refactored Markdown link navigation by introducing MarkdownLinkNavigationData. Legacy URI-based handling has been replaced to streamline file and header navigation while eliminating redundant methods. Instead of performing slow findVirtualFile calls on EDT, the implementation now passes a VirtualFile directly to the openFile and navigateToHeader actions. Related services, DTOs, and mappings were updated accordingly to support the new, more efficient approach.
GitOrigin-RevId: 4545b23b17c55fe191e1b3c1f77617b6c409818d
Introduced `ProcessImagesExtension` to handle image resources in the Markdown browser preview. Added a new remote API (`ProjectStructureRemoteApi`) to retrieve project-specific resources.
GitOrigin-RevId: 9a3e8f02e167c23e4954e9ebdaa58a9bfd2330fd
Introduced a registry flag (`markdown.open.link.fallback`) for controlling the fallback to the previous implementation of Markdown link handling. Also includes refactoring and code adjustments for improved clarity.
GitOrigin-RevId: 2cab3173b9d85f751a17c96e8f8444be6519b22f
Previously, all links in split mode were opened in the browser because ClientHandler had no way of understanding file path links. To fix it, resolveLinkAsFilePath method was added to the backend.
GitOrigin-RevId: 789db4e0770a85546180b259b8a2de447a705f91