mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 04:57:44 +00:00
LibIPC+WindowServer+LibGUI: Detect and highlight unresponsive GUI apps
IPC::ClientConnection now tracks the time since the last time we got a message from the client and calls a virtual function on itself after 3 seconds: may_have_become_unresponsive(). Subclasses of ClientConnection can then react to this if they like. We use this mechanism in WindowServer to send out a friendly Ping message to the client. If he doesn't Pong within 1 second, we mark the client as "unresponsive" and recompose all of his windows with a darkened appearance and amended title until he Pongs us. This is a little on the aggressive side and we should figure out a way to wake up less often. Perhaps this could only be done to windows the user is currently interacting with, for example. Anyways, this is pretty cool! :^)
This commit is contained in:
parent
940fbea3a7
commit
2ce2c4810a
9 changed files with 84 additions and 7 deletions
|
@ -31,6 +31,7 @@
|
|||
#include <LibCore/EventLoop.h>
|
||||
#include <LibCore/LocalSocket.h>
|
||||
#include <LibCore/Object.h>
|
||||
#include <LibCore/Timer.h>
|
||||
#include <LibIPC/Endpoint.h>
|
||||
#include <LibIPC/Message.h>
|
||||
#include <errno.h>
|
||||
|
@ -91,12 +92,21 @@ public:
|
|||
m_client_pid = creds.pid;
|
||||
add_child(socket);
|
||||
m_socket->on_ready_to_read = [this] { drain_messages_from_client(); };
|
||||
|
||||
m_responsiveness_timer = Core::Timer::construct();
|
||||
m_responsiveness_timer->set_single_shot(true);
|
||||
m_responsiveness_timer->set_interval(3000);
|
||||
m_responsiveness_timer->on_timeout = [this] {
|
||||
may_have_become_unresponsive();
|
||||
};
|
||||
}
|
||||
|
||||
virtual ~ClientConnection() override
|
||||
{
|
||||
}
|
||||
|
||||
virtual void may_have_become_unresponsive() {}
|
||||
|
||||
void post_message(const Message& message)
|
||||
{
|
||||
// NOTE: If this connection is being shut down, but has not yet been destroyed,
|
||||
|
@ -151,6 +161,9 @@ public:
|
|||
bytes.append(buffer, nread);
|
||||
}
|
||||
|
||||
if (!bytes.is_empty())
|
||||
m_responsiveness_timer->start();
|
||||
|
||||
size_t decoded_bytes = 0;
|
||||
for (size_t index = 0; index < bytes.size(); index += decoded_bytes) {
|
||||
auto remaining_bytes = ByteBuffer::wrap(bytes.data() + index, bytes.size() - index);
|
||||
|
@ -205,6 +218,7 @@ protected:
|
|||
private:
|
||||
Endpoint& m_endpoint;
|
||||
RefPtr<Core::LocalSocket> m_socket;
|
||||
RefPtr<Core::Timer> m_responsiveness_timer;
|
||||
int m_client_id { -1 };
|
||||
int m_client_pid { -1 };
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue