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 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_action_route_pid_allowed_set(uint32_t pid, Eina_Bool allow);
|
||||
|
||||
|
||||
|
||||
E_API void
|
||||
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 **);
|
||||
static Eina_Hash *key_bindings;
|
||||
|
||||
typedef struct Action_Route
|
||||
typedef struct Action_Route_Key
|
||||
{
|
||||
union
|
||||
struct
|
||||
{
|
||||
E_Binding_Key key;
|
||||
} binding;
|
||||
|
@ -584,13 +584,23 @@ typedef struct Action_Route
|
|||
uint32_t state;
|
||||
struct wl_resource *res;
|
||||
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 *
|
||||
_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;
|
||||
Action_Route *ar;
|
||||
Action_Route_Key *ar;
|
||||
E_Binding_Key *binding;
|
||||
|
||||
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
|
||||
_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;
|
||||
}
|
||||
|
||||
|
@ -669,10 +679,10 @@ _action_route_can_override(const E_Binding_Key *binding)
|
|||
}
|
||||
|
||||
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;
|
||||
Action_Route *ar;
|
||||
Action_Route_Key *ar;
|
||||
Eina_Bool update;
|
||||
|
||||
/* FIXME: delete active actions? */
|
||||
|
@ -697,14 +707,14 @@ _e_comp_wl_action_route_grab_del(struct wl_resource *resource)
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -720,7 +730,7 @@ _e_comp_wl_action_route_grab_key(struct wl_client *client, struct wl_resource *r
|
|||
struct wl_resource *rt;
|
||||
E_Binding_Key *binding;
|
||||
Eina_List *l, *ll;
|
||||
Action_Route *ar, *lar;
|
||||
Action_Route_Key *ar, *lar;
|
||||
E_Binding_Context ctxt = E_BINDING_CONTEXT_WINDOW;
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
wl_resource_set_implementation(rt, &_e_action_route_grab_interface, NULL,
|
||||
_e_comp_wl_action_route_grab_del);
|
||||
wl_resource_set_implementation(rt, &_e_action_route_key_grab_interface, NULL,
|
||||
_e_comp_wl_action_route_key_grab_del);
|
||||
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);
|
||||
wl_resource_destroy(rt);
|
||||
return;
|
||||
}
|
||||
ar = E_NEW(Action_Route, 1);
|
||||
ar = E_NEW(Action_Route_Key, 1);
|
||||
ar->mode = mode;
|
||||
ar->res = rt;
|
||||
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);
|
||||
}
|
||||
|
||||
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 =
|
||||
|
@ -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 =
|
||||
{
|
||||
_e_comp_wl_action_route_bind_action,
|
||||
_e_comp_wl_action_route_grab_key,
|
||||
};
|
||||
|
||||
|
|
|
@ -19,6 +19,12 @@
|
|||
<entry name="win" value="8"></entry>
|
||||
<entry name="altgr" value="16"></entry>
|
||||
</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">
|
||||
<description summary="Request a new grab for a key press">
|
||||
</description>
|
||||
|
@ -28,9 +34,31 @@
|
|||
<arg name="mode" type="uint"/>
|
||||
<arg name="modifiers" type="uint"/>
|
||||
<arg name="action" type="string"/>
|
||||
<arg name="params" type="string"/>
|
||||
<arg name="params" type="string" allow-null="true"/>
|
||||
</request>
|
||||
</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">
|
||||
<enum name="state">
|
||||
<entry name="Rejected" value="0"></entry>
|
||||
|
|
Loading…
Reference in New Issue