iwd_manager: coalesce notify into ecore_job to avoid UI freeze
In busy areas iwd emits hundreds of PropertiesChanged per second during scans; each one synchronously rebuilt the popup list and froze the whole compositor. Schedule a single job per main-loop tick instead. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7ef9b6d3bd
commit
5844e2265e
1 changed files with 18 additions and 4 deletions
|
|
@ -3,6 +3,7 @@
|
||||||
#include "iwd_adapter.h"
|
#include "iwd_adapter.h"
|
||||||
#include "iwd_device.h"
|
#include "iwd_device.h"
|
||||||
#include "iwd_network.h"
|
#include "iwd_network.h"
|
||||||
|
#include <Ecore.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
@ -21,7 +22,7 @@ struct _Iwd_Manager
|
||||||
Eina_Hash *networks; /* path → Iwd_Network * */
|
Eina_Hash *networks; /* path → Iwd_Network * */
|
||||||
Eina_List *listeners; /* Listener * */
|
Eina_List *listeners; /* Listener * */
|
||||||
Iwd_State state;
|
Iwd_State state;
|
||||||
Eina_Bool notify_pending;
|
Ecore_Job *notify_job;
|
||||||
|
|
||||||
Iwd_Agent_Passphrase_Cb pass_cb;
|
Iwd_Agent_Passphrase_Cb pass_cb;
|
||||||
void *pass_data;
|
void *pass_data;
|
||||||
|
|
@ -78,10 +79,15 @@ iwd_manager_listener_del(Iwd_Manager *m, Iwd_Manager_Cb cb, void *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
/* Coalesce bursts of D-Bus PropertiesChanged into a single UI refresh per
|
||||||
iwd_manager_notify(Iwd_Manager *m)
|
* main-loop tick. Without this, a busy area (30+ visible networks, scan in
|
||||||
|
* progress) can fire hundreds of notifies per second, each rebuilding the
|
||||||
|
* popup list synchronously and freezing the whole compositor. */
|
||||||
|
static void
|
||||||
|
_notify_job_cb(void *data)
|
||||||
{
|
{
|
||||||
if (!m) return;
|
Iwd_Manager *m = data;
|
||||||
|
m->notify_job = NULL;
|
||||||
_recompute_state(m);
|
_recompute_state(m);
|
||||||
Eina_List *l;
|
Eina_List *l;
|
||||||
Listener *li;
|
Listener *li;
|
||||||
|
|
@ -89,6 +95,13 @@ iwd_manager_notify(Iwd_Manager *m)
|
||||||
li->cb(li->data, m);
|
li->cb(li->data, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
iwd_manager_notify(Iwd_Manager *m)
|
||||||
|
{
|
||||||
|
if (!m || m->notify_job) return;
|
||||||
|
m->notify_job = ecore_job_add(_notify_job_cb, m);
|
||||||
|
}
|
||||||
|
|
||||||
/* ----- state aggregation ---------------------------------------------- */
|
/* ----- state aggregation ---------------------------------------------- */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -253,6 +266,7 @@ void
|
||||||
iwd_manager_free(Iwd_Manager *m)
|
iwd_manager_free(Iwd_Manager *m)
|
||||||
{
|
{
|
||||||
if (!m) return;
|
if (!m) return;
|
||||||
|
if (m->notify_job) ecore_job_del(m->notify_job);
|
||||||
iwd_agent_free(m->agent);
|
iwd_agent_free(m->agent);
|
||||||
iwd_dbus_free(m->dbus);
|
iwd_dbus_free(m->dbus);
|
||||||
eina_hash_free(m->adapters);
|
eina_hash_free(m->adapters);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue