forked from enlightenment/enlightenment
extend key action routing for general action contexts
this allows authorized clients to activate validated actions
This commit is contained in:
parent
8748b197fa
commit
862b02adc8
|
@ -425,6 +425,9 @@ E_API void e_comp_wl_extension_relative_motion_event(uint64_t time_usec, double
|
||||||
E_API void e_comp_wl_extension_pointer_constraints_commit(E_Client *ec);
|
E_API void e_comp_wl_extension_pointer_constraints_commit(E_Client *ec);
|
||||||
E_API Eina_Bool e_comp_wl_extension_pointer_constraints_update(E_Client *ec, int x, int y);
|
E_API Eina_Bool e_comp_wl_extension_pointer_constraints_update(E_Client *ec, int x, int y);
|
||||||
E_API void e_comp_wl_extension_pointer_unconstrain(E_Client *ec);
|
E_API void e_comp_wl_extension_pointer_unconstrain(E_Client *ec);
|
||||||
|
E_API void e_comp_wl_extension_action_route_pid_allowed_set(uint32_t pid, Eina_Bool allow);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
E_API void
|
E_API void
|
||||||
e_policy_wl_aux_message_send(E_Client *ec,
|
e_policy_wl_aux_message_send(E_Client *ec,
|
||||||
|
|
|
@ -574,9 +574,9 @@ _e_comp_wl_zwp_pointer_constraints_v1_confine_pointer(struct wl_client *client,
|
||||||
extern E_Action *(*e_binding_key_list_cb)(E_Binding_Context, Ecore_Event_Key*, E_Binding_Modifier, E_Binding_Key **);
|
extern E_Action *(*e_binding_key_list_cb)(E_Binding_Context, Ecore_Event_Key*, E_Binding_Modifier, E_Binding_Key **);
|
||||||
static Eina_Hash *key_bindings;
|
static Eina_Hash *key_bindings;
|
||||||
|
|
||||||
typedef struct Action_Route
|
typedef struct Action_Route_Key
|
||||||
{
|
{
|
||||||
union
|
struct
|
||||||
{
|
{
|
||||||
E_Binding_Key key;
|
E_Binding_Key key;
|
||||||
} binding;
|
} binding;
|
||||||
|
@ -584,13 +584,23 @@ typedef struct Action_Route
|
||||||
uint32_t state;
|
uint32_t state;
|
||||||
struct wl_resource *res;
|
struct wl_resource *res;
|
||||||
struct wl_resource *surface;
|
struct wl_resource *surface;
|
||||||
} Action_Route;
|
} Action_Route_Key;
|
||||||
|
|
||||||
|
typedef struct Action_Route_Bind
|
||||||
|
{
|
||||||
|
E_Action *action;
|
||||||
|
uint32_t state;
|
||||||
|
struct wl_resource *res;
|
||||||
|
Evas_Object *end_obj;
|
||||||
|
} Action_Route_Bind;
|
||||||
|
|
||||||
|
static Eina_Hash *allowed_pids;
|
||||||
|
|
||||||
static E_Action *
|
static E_Action *
|
||||||
_action_route_key_list_cb(E_Binding_Context ctxt, Ecore_Event_Key *ev, E_Binding_Modifier mod, E_Binding_Key **bind_ret)
|
_action_route_key_list_cb(E_Binding_Context ctxt, Ecore_Event_Key *ev, E_Binding_Modifier mod, E_Binding_Key **bind_ret)
|
||||||
{
|
{
|
||||||
Eina_List *l, *ll;
|
Eina_List *l, *ll;
|
||||||
Action_Route *ar;
|
Action_Route_Key *ar;
|
||||||
E_Binding_Key *binding;
|
E_Binding_Key *binding;
|
||||||
|
|
||||||
if (bind_ret) *bind_ret = NULL;
|
if (bind_ret) *bind_ret = NULL;
|
||||||
|
@ -651,9 +661,9 @@ _action_route_key_list_cb(E_Binding_Context ctxt, Ecore_Event_Key *ev, E_Binding
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_action_route_is_allowed(const char *action, const char *params)
|
_action_route_key_is_allowed(const char *action EINA_UNUSED, const char *params EINA_UNUSED)
|
||||||
{
|
{
|
||||||
/* FIXME: allow 1-2 bindings maybe */
|
/* FIXME: no users of this yet... */
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -669,10 +679,10 @@ _action_route_can_override(const E_Binding_Key *binding)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_e_comp_wl_action_route_grab_del(struct wl_resource *resource)
|
_e_comp_wl_action_route_key_grab_del(struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
Eina_List *l, *ll;
|
Eina_List *l, *ll;
|
||||||
Action_Route *ar;
|
Action_Route_Key *ar;
|
||||||
Eina_Bool update;
|
Eina_Bool update;
|
||||||
|
|
||||||
/* FIXME: delete active actions? */
|
/* FIXME: delete active actions? */
|
||||||
|
@ -697,14 +707,14 @@ _e_comp_wl_action_route_grab_del(struct wl_resource *resource)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_e_comp_wl_action_route_grab_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
_e_comp_wl_action_route_key_grab_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
_e_comp_wl_action_route_grab_del(resource);
|
wl_resource_destroy(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct action_route_key_grab_interface _e_action_route_grab_interface =
|
static const struct action_route_key_grab_interface _e_action_route_key_grab_interface =
|
||||||
{
|
{
|
||||||
_e_comp_wl_action_route_grab_destroy,
|
_e_comp_wl_action_route_key_grab_destroy,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -720,7 +730,7 @@ _e_comp_wl_action_route_grab_key(struct wl_client *client, struct wl_resource *r
|
||||||
struct wl_resource *rt;
|
struct wl_resource *rt;
|
||||||
E_Binding_Key *binding;
|
E_Binding_Key *binding;
|
||||||
Eina_List *l, *ll;
|
Eina_List *l, *ll;
|
||||||
Action_Route *ar, *lar;
|
Action_Route_Key *ar, *lar;
|
||||||
E_Binding_Context ctxt = E_BINDING_CONTEXT_WINDOW;
|
E_Binding_Context ctxt = E_BINDING_CONTEXT_WINDOW;
|
||||||
|
|
||||||
rt = wl_resource_create(client, &action_route_key_grab_interface, 1, id);
|
rt = wl_resource_create(client, &action_route_key_grab_interface, 1, id);
|
||||||
|
@ -730,16 +740,16 @@ _e_comp_wl_action_route_grab_key(struct wl_client *client, struct wl_resource *r
|
||||||
wl_client_post_no_memory(client);
|
wl_client_post_no_memory(client);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wl_resource_set_implementation(rt, &_e_action_route_grab_interface, NULL,
|
wl_resource_set_implementation(rt, &_e_action_route_key_grab_interface, NULL,
|
||||||
_e_comp_wl_action_route_grab_del);
|
_e_comp_wl_action_route_key_grab_del);
|
||||||
binding = e_bindings_key_find(key, modifiers, 0);
|
binding = e_bindings_key_find(key, modifiers, 0);
|
||||||
if ((!_action_route_is_allowed(action, params)) || (!_action_route_can_override(binding)))
|
if ((!_action_route_key_is_allowed(action, params)) || (!_action_route_can_override(binding)))
|
||||||
{
|
{
|
||||||
action_route_key_grab_send_status(rt, ACTION_ROUTE_KEY_GRAB_STATE_REJECTED);
|
action_route_key_grab_send_status(rt, ACTION_ROUTE_KEY_GRAB_STATE_REJECTED);
|
||||||
wl_resource_destroy(rt);
|
wl_resource_destroy(rt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ar = E_NEW(Action_Route, 1);
|
ar = E_NEW(Action_Route_Key, 1);
|
||||||
ar->mode = mode;
|
ar->mode = mode;
|
||||||
ar->res = rt;
|
ar->res = rt;
|
||||||
ar->surface = surface;
|
ar->surface = surface;
|
||||||
|
@ -782,6 +792,126 @@ _e_comp_wl_action_route_grab_key(struct wl_client *client, struct wl_resource *r
|
||||||
action_route_key_grab_send_status(ar->res, ar->state);
|
action_route_key_grab_send_status(ar->res, ar->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_comp_wl_action_route_bind_menu_end(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||||
|
{
|
||||||
|
Action_Route_Bind *ar = data;
|
||||||
|
evas_object_event_callback_del_full(obj, EVAS_CALLBACK_HIDE,
|
||||||
|
_e_comp_wl_action_route_bind_menu_end, ar);
|
||||||
|
action_route_bind_send_end(ar->res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_comp_wl_action_route_bind_action_del(struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
Action_Route_Bind *ar = wl_resource_get_user_data(resource);
|
||||||
|
|
||||||
|
if (strstr(ar->action->name, "menu"))
|
||||||
|
{
|
||||||
|
E_Menu *m = e_menu_active_get();
|
||||||
|
if (!m) return;
|
||||||
|
evas_object_event_callback_del_full(m->comp_object, EVAS_CALLBACK_HIDE,
|
||||||
|
_e_comp_wl_action_route_bind_menu_end, ar);
|
||||||
|
}
|
||||||
|
|
||||||
|
e_object_unref(E_OBJECT(ar->action));
|
||||||
|
free(ar);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_comp_wl_action_route_bind_action_activate(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *params)
|
||||||
|
{
|
||||||
|
Action_Route_Bind *ar = wl_resource_get_user_data(resource);
|
||||||
|
if (!ar) return;
|
||||||
|
ar->action->func.go(NULL, params);
|
||||||
|
if (strstr(ar->action->name, "menu"))
|
||||||
|
{
|
||||||
|
E_Menu *m = e_menu_active_get();
|
||||||
|
if (!m) return;
|
||||||
|
evas_object_event_callback_add(m->comp_object, EVAS_CALLBACK_HIDE,
|
||||||
|
_e_comp_wl_action_route_bind_menu_end, ar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_comp_wl_action_route_bind_action_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct action_route_bind_interface _e_action_route_bind_action_interface =
|
||||||
|
{
|
||||||
|
_e_comp_wl_action_route_bind_action_activate,
|
||||||
|
_e_comp_wl_action_route_bind_action_destroy,
|
||||||
|
};
|
||||||
|
|
||||||
|
static E_Action *
|
||||||
|
_action_route_bind_is_allowed(int32_t pid, const char *action)
|
||||||
|
{
|
||||||
|
const char **b, *blacklist[] =
|
||||||
|
{
|
||||||
|
"exit_now",
|
||||||
|
"halt_now",
|
||||||
|
"suspend_now",
|
||||||
|
"hibernate_now",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
if (!allowed_pids) return NULL;
|
||||||
|
if (!eina_hash_find(allowed_pids, &pid)) return NULL;
|
||||||
|
if ((!action[0])) return NULL;
|
||||||
|
if (!strncmp(action, "module_", sizeof("module_") - 1)) return NULL;
|
||||||
|
for (b = blacklist; *b; b++)
|
||||||
|
if (eina_streq(*b, action)) return NULL;
|
||||||
|
return e_action_find(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_comp_wl_action_route_bind_action(struct wl_client *client, struct wl_resource *resource EINA_UNUSED,
|
||||||
|
uint32_t id,
|
||||||
|
const char *action)
|
||||||
|
{
|
||||||
|
struct wl_resource *rt;
|
||||||
|
Action_Route_Bind *ar;
|
||||||
|
E_Action *act;
|
||||||
|
int32_t pid;
|
||||||
|
|
||||||
|
rt = wl_resource_create(client, &action_route_bind_interface, 1, id);
|
||||||
|
if (!rt)
|
||||||
|
{
|
||||||
|
ERR("Could not create action route");
|
||||||
|
wl_client_post_no_memory(client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wl_resource_set_implementation(rt, &_e_action_route_bind_action_interface, NULL,
|
||||||
|
_e_comp_wl_action_route_bind_action_del);
|
||||||
|
wl_client_get_credentials(client, &pid, NULL, NULL);
|
||||||
|
act = _action_route_bind_is_allowed(pid, action);
|
||||||
|
if (!act)
|
||||||
|
{
|
||||||
|
action_route_bind_send_status(rt, ACTION_ROUTE_BIND_STATE_REJECTED);
|
||||||
|
wl_resource_destroy(rt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ar = E_NEW(Action_Route_Bind, 1);
|
||||||
|
ar->res = rt;
|
||||||
|
ar->action = act;
|
||||||
|
e_object_ref(E_OBJECT(act));
|
||||||
|
ar->state = ACTION_ROUTE_BIND_STATE_ACTIVE;
|
||||||
|
wl_resource_set_user_data(rt, ar);
|
||||||
|
action_route_bind_send_status(ar->res, ar->state);
|
||||||
|
}
|
||||||
|
|
||||||
|
E_API void
|
||||||
|
e_comp_wl_extension_action_route_pid_allowed_set(uint32_t pid, Eina_Bool allow)
|
||||||
|
{
|
||||||
|
if (!allowed_pids)
|
||||||
|
allowed_pids = eina_hash_int32_new(NULL);
|
||||||
|
if (allow)
|
||||||
|
eina_hash_add(allowed_pids, &pid, (void*)1);
|
||||||
|
else
|
||||||
|
eina_hash_del_by_key(allowed_pids, &pid);
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static const struct zwp_e_session_recovery_interface _e_session_recovery_interface =
|
static const struct zwp_e_session_recovery_interface _e_session_recovery_interface =
|
||||||
|
@ -823,6 +953,7 @@ static const struct zwp_pointer_constraints_v1_interface _e_zwp_pointer_constrai
|
||||||
|
|
||||||
static const struct action_route_interface _e_action_route_interface =
|
static const struct action_route_interface _e_action_route_interface =
|
||||||
{
|
{
|
||||||
|
_e_comp_wl_action_route_bind_action,
|
||||||
_e_comp_wl_action_route_grab_key,
|
_e_comp_wl_action_route_grab_key,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,12 @@
|
||||||
<entry name="win" value="8"></entry>
|
<entry name="win" value="8"></entry>
|
||||||
<entry name="altgr" value="16"></entry>
|
<entry name="altgr" value="16"></entry>
|
||||||
</enum>
|
</enum>
|
||||||
|
<request name="bind_action">
|
||||||
|
<description summary="Request a new grab for a key press">
|
||||||
|
</description>
|
||||||
|
<arg name="id" type="new_id" interface="action_route_bind"/>
|
||||||
|
<arg name="action" type="string"/>
|
||||||
|
</request>
|
||||||
<request name="grab_key">
|
<request name="grab_key">
|
||||||
<description summary="Request a new grab for a key press">
|
<description summary="Request a new grab for a key press">
|
||||||
</description>
|
</description>
|
||||||
|
@ -28,9 +34,31 @@
|
||||||
<arg name="mode" type="uint"/>
|
<arg name="mode" type="uint"/>
|
||||||
<arg name="modifiers" type="uint"/>
|
<arg name="modifiers" type="uint"/>
|
||||||
<arg name="action" type="string"/>
|
<arg name="action" type="string"/>
|
||||||
<arg name="params" type="string"/>
|
<arg name="params" type="string" allow-null="true"/>
|
||||||
</request>
|
</request>
|
||||||
</interface>
|
</interface>
|
||||||
|
<interface name="action_route_bind" version="1">
|
||||||
|
<enum name="state">
|
||||||
|
<entry name="Rejected" value="0"></entry>
|
||||||
|
<entry name="Active" value="1"></entry>
|
||||||
|
<entry name="Queued" value="2"></entry>
|
||||||
|
</enum>
|
||||||
|
<event name="status">
|
||||||
|
<description summary="Status update on a bind request"></description>
|
||||||
|
<arg name="state" type="uint"/>
|
||||||
|
</event>
|
||||||
|
<request name="activate">
|
||||||
|
<description summary="Activate a bind"/>
|
||||||
|
<arg name="params" type="string" allow-null="true"/>
|
||||||
|
</request>
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="Destroy a requested bind">
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
<event name="end">
|
||||||
|
<description summary="The bind has completed execution"/>
|
||||||
|
</event>
|
||||||
|
</interface>
|
||||||
<interface name="action_route_key_grab" version="1">
|
<interface name="action_route_key_grab" version="1">
|
||||||
<enum name="state">
|
<enum name="state">
|
||||||
<entry name="Rejected" value="0"></entry>
|
<entry name="Rejected" value="0"></entry>
|
||||||
|
|
Loading…
Reference in New Issue