forked from enlightenment/enlightenment
e_client_volume: Reparent sink if a new window comes and match this one
Summary: This commit avoid multiple windows got the same sink. Like launching rage from terminology, gstreamer sink could be associated with terminology and rage window too. Reviewers: raster, devilhorns Subscribers: cedric, zmike Tags: #enlightenment-git Differential Revision: https://phab.enlightenment.org/D8929
This commit is contained in:
parent
f4c1ba959e
commit
eae3cd37e8
|
@ -45,6 +45,7 @@ static int _sink_input_min_get(void *data);
|
||||||
static int _sink_input_max_get(void *data);
|
static int _sink_input_max_get(void *data);
|
||||||
static const char *_sink_input_name_get(void *data);
|
static const char *_sink_input_name_get(void *data);
|
||||||
static pid_t _get_ppid(pid_t pid);
|
static pid_t _get_ppid(pid_t pid);
|
||||||
|
static E_Client_Volume_Sink *_sink_input_e_client_volume_sink_find(Emix_Sink_Input *input, pid_t *ret_pid);
|
||||||
static void _sink_input_event(int type, Emix_Sink_Input *input);
|
static void _sink_input_event(int type, Emix_Sink_Input *input);
|
||||||
static void _events_cb(void *data, enum Emix_Event type, void *event_info);
|
static void _events_cb(void *data, enum Emix_Event type, void *event_info);
|
||||||
static Eina_Bool _desklock_cb(void *data, int type, void *info);
|
static Eina_Bool _desklock_cb(void *data, int type, void *info);
|
||||||
|
@ -523,51 +524,75 @@ _get_ppid(pid_t pid)
|
||||||
return ppid;
|
return ppid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static E_Client_Volume_Sink *
|
||||||
|
_sink_input_e_client_volume_sink_find(Emix_Sink_Input *input, pid_t *ret_pid)
|
||||||
|
{
|
||||||
|
Eina_List *clients, *l;
|
||||||
|
E_Client *ec;
|
||||||
|
E_Client_Volume_Sink *sink = NULL;
|
||||||
|
pid_t pid;
|
||||||
|
Eina_Bool found = EINA_FALSE;
|
||||||
|
|
||||||
|
pid = input->pid;
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH(_client_sinks, l, sink)
|
||||||
|
{
|
||||||
|
if (sink->data == input)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if ((pid <= 1) || (pid == getpid())) break;
|
||||||
|
clients = e_client_focus_stack_get();
|
||||||
|
EINA_LIST_FOREACH(clients, l, ec)
|
||||||
|
{
|
||||||
|
if ((ec->netwm.pid == pid) && (!ec->parent))
|
||||||
|
{
|
||||||
|
DBG("Sink found the client %s",
|
||||||
|
e_client_util_name_get(ec));
|
||||||
|
if (!sink)
|
||||||
|
{
|
||||||
|
DBG("Create a new client_volume_sink");
|
||||||
|
sink = e_client_volume_sink_new(_sink_input_get,
|
||||||
|
_sink_input_set,
|
||||||
|
_sink_input_min_get,
|
||||||
|
_sink_input_max_get,
|
||||||
|
_sink_input_name_get,
|
||||||
|
input);
|
||||||
|
}
|
||||||
|
e_client_volume_sink_append(ec, sink);
|
||||||
|
_client_sinks = eina_list_append(_client_sinks, sink);
|
||||||
|
found = EINA_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) break;
|
||||||
|
pid = _get_ppid(pid);
|
||||||
|
}
|
||||||
|
if (ret_pid) *ret_pid = pid;
|
||||||
|
return found ? sink : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_sink_input_event(int type, Emix_Sink_Input *input)
|
_sink_input_event(int type, Emix_Sink_Input *input)
|
||||||
{
|
{
|
||||||
Eina_List *clients, *l, *ll;
|
Eina_List *l;
|
||||||
E_Client *ec;
|
|
||||||
E_Client_Volume_Sink *sink;
|
E_Client_Volume_Sink *sink;
|
||||||
pid_t pid;
|
|
||||||
Eina_Bool found = EINA_FALSE;
|
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case EMIX_SINK_INPUT_ADDED_EVENT:
|
case EMIX_SINK_INPUT_ADDED_EVENT:
|
||||||
pid = input->pid;
|
_sink_input_e_client_volume_sink_find(input, NULL);
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
if ((pid <= 1) || (pid == getpid())) return;
|
|
||||||
clients = e_client_focus_stack_get();
|
|
||||||
EINA_LIST_FOREACH(clients, l, ec)
|
|
||||||
{
|
|
||||||
if ((ec->netwm.pid == pid) && (!ec->parent))
|
|
||||||
{
|
|
||||||
DBG("Sink found the client %s",
|
|
||||||
e_client_util_name_get(ec));
|
|
||||||
sink = e_client_volume_sink_new(_sink_input_get,
|
|
||||||
_sink_input_set,
|
|
||||||
_sink_input_min_get,
|
|
||||||
_sink_input_max_get,
|
|
||||||
_sink_input_name_get,
|
|
||||||
input);
|
|
||||||
e_client_volume_sink_append(ec, sink);
|
|
||||||
_client_sinks = eina_list_append(_client_sinks, sink);
|
|
||||||
found = EINA_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found) break;
|
|
||||||
pid = _get_ppid(pid);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case EMIX_SINK_INPUT_REMOVED_EVENT:
|
case EMIX_SINK_INPUT_REMOVED_EVENT:
|
||||||
EINA_LIST_FOREACH_SAFE(_client_sinks, l, ll, sink)
|
EINA_LIST_FOREACH(_client_sinks, l, sink)
|
||||||
{
|
{
|
||||||
if (sink->data == input)
|
if (sink->data == input)
|
||||||
{
|
{
|
||||||
|
DBG("Client sink del");
|
||||||
e_client_volume_sink_del(sink);
|
e_client_volume_sink_del(sink);
|
||||||
_client_sinks = eina_list_remove_list(_client_sinks, l);
|
_client_sinks = eina_list_remove_list(_client_sinks, l);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -953,39 +978,33 @@ _client_mixer_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_e_client_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
_e_client_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
||||||
{
|
{
|
||||||
E_Event_Client *ev;
|
E_Event_Client *ev;
|
||||||
Eina_List *l;
|
Eina_List *l, *ll;
|
||||||
Emix_Sink_Input *input;
|
Emix_Sink_Input *input;
|
||||||
pid_t pid;
|
E_Client *ec;
|
||||||
E_Client_Volume_Sink *sink;
|
E_Client_Volume_Sink *sink;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
ev = event;
|
ev = event;
|
||||||
|
|
||||||
if (ev->ec->parent) return ECORE_CALLBACK_PASS_ON;
|
if (ev->ec->parent) return ECORE_CALLBACK_PASS_ON;
|
||||||
EINA_LIST_FOREACH((Eina_List *)emix_sink_inputs_get(), l, input)
|
EINA_LIST_FOREACH((Eina_List *)emix_sink_inputs_get(), l, input)
|
||||||
{
|
{
|
||||||
pid = input->pid;
|
sink = _sink_input_e_client_volume_sink_find(input, &pid);
|
||||||
while (42)
|
if (sink)
|
||||||
{
|
{
|
||||||
if (pid <= 1 || pid == getpid()) return ECORE_CALLBACK_PASS_ON;
|
EINA_LIST_FOREACH_SAFE(sink->clients, l, ll, ec)
|
||||||
if (ev->ec->netwm.pid == pid)
|
{
|
||||||
{
|
if (ec->netwm.pid != pid)
|
||||||
DBG("Client(%s) found a sink input",
|
{
|
||||||
e_client_util_name_get(ev->ec));
|
DBG("Clean invalid client sink %s",
|
||||||
sink = e_client_volume_sink_new(_sink_input_get,
|
e_client_util_name_get(ec));
|
||||||
_sink_input_set,
|
e_client_volume_sink_remove(ec, sink);
|
||||||
_sink_input_min_get,
|
}
|
||||||
_sink_input_max_get,
|
}
|
||||||
_sink_input_name_get,
|
}
|
||||||
input);
|
}
|
||||||
e_client_volume_sink_append(ev->ec, sink);
|
return ECORE_CALLBACK_PASS_ON;
|
||||||
_client_sinks = eina_list_append(_client_sinks, sink);
|
|
||||||
return ECORE_CALLBACK_PASS_ON;
|
|
||||||
}
|
|
||||||
pid = _get_ppid(pid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ECORE_CALLBACK_PASS_ON;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
|
|
Loading…
Reference in New Issue