implement action routing for wayland clients
this allows a wayland client to request that a given action name be bound to the requested surface using a mode to restrict activation of the binding modes include: * shared - activated when any surface from the client has focus * topmost - activated when the requested surface has focus and is the topmost client * exclusive - activated when the requested surface has focus; blocks other action routes #SamsungFeatures Signed-off-by: Mike Blumenkrantz <zmike@osg.samsung.com>
This commit is contained in:
parent
01b7cf8227
commit
8748b197fa
|
@ -442,6 +442,8 @@ src/bin/generated/session-recovery-protocol.c \
|
||||||
src/bin/generated/session-recovery-server-protocol.h \
|
src/bin/generated/session-recovery-server-protocol.h \
|
||||||
src/bin/generated/www-protocol.c \
|
src/bin/generated/www-protocol.c \
|
||||||
src/bin/generated/www-server-protocol.h \
|
src/bin/generated/www-server-protocol.h \
|
||||||
|
src/bin/generated/action_route-protocol.c \
|
||||||
|
src/bin/generated/action_route-server-protocol.h \
|
||||||
src/bin/generated/xdg-foreign-unstable-v1-protocol.c \
|
src/bin/generated/xdg-foreign-unstable-v1-protocol.c \
|
||||||
src/bin/generated/xdg-foreign-unstable-v1-server-protocol.h \
|
src/bin/generated/xdg-foreign-unstable-v1-server-protocol.h \
|
||||||
src/bin/generated/relative-pointer-unstable-v1-protocol.c \
|
src/bin/generated/relative-pointer-unstable-v1-protocol.c \
|
||||||
|
|
|
@ -7,7 +7,6 @@ static void _e_bindings_edge_free(E_Binding_Edge *bind);
|
||||||
static void _e_bindings_signal_free(E_Binding_Signal *bind);
|
static void _e_bindings_signal_free(E_Binding_Signal *bind);
|
||||||
static void _e_bindings_wheel_free(E_Binding_Wheel *bind);
|
static void _e_bindings_wheel_free(E_Binding_Wheel *bind);
|
||||||
static void _e_bindings_acpi_free(E_Binding_Acpi *bind);
|
static void _e_bindings_acpi_free(E_Binding_Acpi *bind);
|
||||||
static int _e_bindings_context_match(E_Binding_Context bctxt, E_Binding_Context ctxt);
|
|
||||||
static E_Binding_Modifier _e_bindings_modifiers(unsigned int modifiers);
|
static E_Binding_Modifier _e_bindings_modifiers(unsigned int modifiers);
|
||||||
static Eina_Bool _e_bindings_edge_cb_timer(void *data);
|
static Eina_Bool _e_bindings_edge_cb_timer(void *data);
|
||||||
|
|
||||||
|
@ -22,6 +21,8 @@ static Eina_List *acpi_bindings = NULL;
|
||||||
|
|
||||||
static unsigned int bindings_disabled = 0;
|
static unsigned int bindings_disabled = 0;
|
||||||
|
|
||||||
|
EINTERN E_Action *(*e_binding_key_list_cb)(E_Binding_Context, Ecore_Event_Key*, E_Binding_Modifier, E_Binding_Key **);
|
||||||
|
|
||||||
typedef struct _E_Binding_Edge_Data E_Binding_Edge_Data;
|
typedef struct _E_Binding_Edge_Data E_Binding_Edge_Data;
|
||||||
|
|
||||||
struct _E_Binding_Edge_Data
|
struct _E_Binding_Edge_Data
|
||||||
|
@ -382,7 +383,7 @@ e_bindings_mouse_grab(E_Binding_Context ctxt, Ecore_X_Window win)
|
||||||
EINA_LIST_FOREACH(mouse_bindings, l, binding)
|
EINA_LIST_FOREACH(mouse_bindings, l, binding)
|
||||||
{
|
{
|
||||||
if (binding->ctxt == E_BINDING_CONTEXT_ANY) continue;
|
if (binding->ctxt == E_BINDING_CONTEXT_ANY) continue;
|
||||||
if (_e_bindings_context_match(binding->ctxt, ctxt))
|
if (e_bindings_context_match(binding->ctxt, ctxt))
|
||||||
{
|
{
|
||||||
#ifndef HAVE_WAYLAND_ONLY
|
#ifndef HAVE_WAYLAND_ONLY
|
||||||
ecore_x_window_button_grab(win, binding->button,
|
ecore_x_window_button_grab(win, binding->button,
|
||||||
|
@ -408,7 +409,7 @@ e_bindings_mouse_ungrab(E_Binding_Context ctxt, Ecore_X_Window win)
|
||||||
EINA_LIST_FOREACH(mouse_bindings, l, binding)
|
EINA_LIST_FOREACH(mouse_bindings, l, binding)
|
||||||
{
|
{
|
||||||
if (binding->ctxt == E_BINDING_CONTEXT_ANY) continue;
|
if (binding->ctxt == E_BINDING_CONTEXT_ANY) continue;
|
||||||
if (_e_bindings_context_match(binding->ctxt, ctxt))
|
if (e_bindings_context_match(binding->ctxt, ctxt))
|
||||||
{
|
{
|
||||||
#ifndef HAVE_WAYLAND_ONLY
|
#ifndef HAVE_WAYLAND_ONLY
|
||||||
ecore_x_window_button_ungrab(win, binding->button,
|
ecore_x_window_button_ungrab(win, binding->button,
|
||||||
|
@ -444,7 +445,7 @@ e_bindings_mouse_button_find(E_Binding_Context ctxt, E_Binding_Event_Mouse_Butto
|
||||||
if ((binding->button == (int)ev->button) &&
|
if ((binding->button == (int)ev->button) &&
|
||||||
((binding->any_mod) || (binding->mod == ev->modifiers)))
|
((binding->any_mod) || (binding->mod == ev->modifiers)))
|
||||||
{
|
{
|
||||||
if (!_e_bindings_context_match(binding->ctxt, ctxt)) continue;
|
if (!e_bindings_context_match(binding->ctxt, ctxt)) continue;
|
||||||
if (act && (binding->ctxt == E_BINDING_CONTEXT_ANY)) continue;
|
if (act && (binding->ctxt == E_BINDING_CONTEXT_ANY)) continue;
|
||||||
act = e_action_find(binding->action);
|
act = e_action_find(binding->action);
|
||||||
if (bind_ret) *bind_ret = binding;
|
if (bind_ret) *bind_ret = binding;
|
||||||
|
@ -620,7 +621,7 @@ e_bindings_key_grab(E_Binding_Context ctxt, Ecore_X_Window win)
|
||||||
|
|
||||||
EINA_LIST_FOREACH(key_bindings, l, binding)
|
EINA_LIST_FOREACH(key_bindings, l, binding)
|
||||||
{
|
{
|
||||||
if (_e_bindings_context_match(binding->ctxt, ctxt))
|
if (e_bindings_context_match(binding->ctxt, ctxt))
|
||||||
{
|
{
|
||||||
if (e_bindings_key_allowed(binding->key))
|
if (e_bindings_key_allowed(binding->key))
|
||||||
{
|
{
|
||||||
|
@ -644,7 +645,7 @@ e_bindings_key_ungrab(E_Binding_Context ctxt, Ecore_X_Window win)
|
||||||
|
|
||||||
EINA_LIST_FOREACH(key_bindings, l, binding)
|
EINA_LIST_FOREACH(key_bindings, l, binding)
|
||||||
{
|
{
|
||||||
if (_e_bindings_context_match(binding->ctxt, ctxt))
|
if (e_bindings_context_match(binding->ctxt, ctxt))
|
||||||
{
|
{
|
||||||
if (e_bindings_key_allowed(binding->key))
|
if (e_bindings_key_allowed(binding->key))
|
||||||
{
|
{
|
||||||
|
@ -701,12 +702,18 @@ e_bindings_key_event_find(E_Binding_Context ctxt, Ecore_Event_Key *ev, E_Binding
|
||||||
E_Action *act = NULL;
|
E_Action *act = NULL;
|
||||||
|
|
||||||
mod = _e_bindings_modifiers(ev->modifiers);
|
mod = _e_bindings_modifiers(ev->modifiers);
|
||||||
|
if (e_binding_key_list_cb)
|
||||||
|
{
|
||||||
|
act = e_binding_key_list_cb(ctxt, ev, mod, bind_ret);
|
||||||
|
if (act) return act;
|
||||||
|
if (bind_ret) *bind_ret = NULL;
|
||||||
|
}
|
||||||
EINA_LIST_FOREACH(key_bindings, l, binding)
|
EINA_LIST_FOREACH(key_bindings, l, binding)
|
||||||
{
|
{
|
||||||
if ((binding->key) && ((!strcmp(binding->key, ev->key)) || (!strcmp(binding->key, ev->keyname))) &&
|
if ((binding->key) && ((!strcmp(binding->key, ev->key)) || (!strcmp(binding->key, ev->keyname))) &&
|
||||||
((binding->any_mod) || (binding->mod == mod)))
|
((binding->any_mod) || (binding->mod == mod)))
|
||||||
{
|
{
|
||||||
if (!_e_bindings_context_match(binding->ctxt, ctxt)) continue;
|
if (!e_bindings_context_match(binding->ctxt, ctxt)) continue;
|
||||||
if (act && (binding->ctxt == E_BINDING_CONTEXT_ANY)) continue;
|
if (act && (binding->ctxt == E_BINDING_CONTEXT_ANY)) continue;
|
||||||
act = e_action_find(binding->action);
|
act = e_action_find(binding->action);
|
||||||
if (bind_ret) *bind_ret = binding;
|
if (bind_ret) *bind_ret = binding;
|
||||||
|
@ -866,7 +873,7 @@ e_bindings_edge_event_find(E_Binding_Context ctxt, E_Event_Zone_Edge *ev, Eina_B
|
||||||
((binding->drag_only == ev->drag) || ev->drag) &&
|
((binding->drag_only == ev->drag) || ev->drag) &&
|
||||||
((binding->any_mod) || (binding->mod == mod)))
|
((binding->any_mod) || (binding->mod == mod)))
|
||||||
{
|
{
|
||||||
if (!_e_bindings_context_match(binding->ctxt, ctxt)) continue;
|
if (!e_bindings_context_match(binding->ctxt, ctxt)) continue;
|
||||||
if (act && (binding->ctxt == E_BINDING_CONTEXT_ANY)) continue;
|
if (act && (binding->ctxt == E_BINDING_CONTEXT_ANY)) continue;
|
||||||
act = e_action_find(binding->action);
|
act = e_action_find(binding->action);
|
||||||
if (bind_ret) *bind_ret = binding;
|
if (bind_ret) *bind_ret = binding;
|
||||||
|
@ -1037,7 +1044,7 @@ e_bindings_signal_find(E_Binding_Context ctxt, const char *sig, const char *src,
|
||||||
(e_util_glob_match(src, binding->src)) &&
|
(e_util_glob_match(src, binding->src)) &&
|
||||||
((binding->any_mod) || (binding->mod == mod)))
|
((binding->any_mod) || (binding->mod == mod)))
|
||||||
{
|
{
|
||||||
if (!_e_bindings_context_match(binding->ctxt, ctxt)) continue;
|
if (!e_bindings_context_match(binding->ctxt, ctxt)) continue;
|
||||||
if (act && (binding->ctxt == E_BINDING_CONTEXT_ANY)) continue;
|
if (act && (binding->ctxt == E_BINDING_CONTEXT_ANY)) continue;
|
||||||
act = e_action_find(binding->action);
|
act = e_action_find(binding->action);
|
||||||
if (bind_ret) *bind_ret = binding;
|
if (bind_ret) *bind_ret = binding;
|
||||||
|
@ -1120,7 +1127,7 @@ e_bindings_wheel_grab(E_Binding_Context ctxt, Ecore_X_Window win)
|
||||||
EINA_LIST_FOREACH(wheel_bindings, l, binding)
|
EINA_LIST_FOREACH(wheel_bindings, l, binding)
|
||||||
{
|
{
|
||||||
if (binding->ctxt == E_BINDING_CONTEXT_ANY) continue;
|
if (binding->ctxt == E_BINDING_CONTEXT_ANY) continue;
|
||||||
if (_e_bindings_context_match(binding->ctxt, ctxt))
|
if (e_bindings_context_match(binding->ctxt, ctxt))
|
||||||
{
|
{
|
||||||
int button = 0;
|
int button = 0;
|
||||||
|
|
||||||
|
@ -1160,7 +1167,7 @@ e_bindings_wheel_ungrab(E_Binding_Context ctxt, Ecore_X_Window win)
|
||||||
EINA_LIST_FOREACH(wheel_bindings, l, binding)
|
EINA_LIST_FOREACH(wheel_bindings, l, binding)
|
||||||
{
|
{
|
||||||
if (binding->ctxt == E_BINDING_CONTEXT_ANY) continue;
|
if (binding->ctxt == E_BINDING_CONTEXT_ANY) continue;
|
||||||
if (_e_bindings_context_match(binding->ctxt, ctxt))
|
if (e_bindings_context_match(binding->ctxt, ctxt))
|
||||||
{
|
{
|
||||||
int button = 0;
|
int button = 0;
|
||||||
|
|
||||||
|
@ -1214,7 +1221,7 @@ e_bindings_wheel_find(E_Binding_Context ctxt, E_Binding_Event_Wheel *ev, E_Bindi
|
||||||
(((binding->z < 0) && (ev->z < 0)) || ((binding->z > 0) && (ev->z > 0))) &&
|
(((binding->z < 0) && (ev->z < 0)) || ((binding->z > 0) && (ev->z > 0))) &&
|
||||||
((binding->any_mod) || (binding->mod == ev->modifiers)))
|
((binding->any_mod) || (binding->mod == ev->modifiers)))
|
||||||
{
|
{
|
||||||
if (!_e_bindings_context_match(binding->ctxt, ctxt)) continue;
|
if (!e_bindings_context_match(binding->ctxt, ctxt)) continue;
|
||||||
if (act && (binding->ctxt == E_BINDING_CONTEXT_ANY)) continue;
|
if (act && (binding->ctxt == E_BINDING_CONTEXT_ANY)) continue;
|
||||||
act = e_action_find(binding->action);
|
act = e_action_find(binding->action);
|
||||||
if (bind_ret) *bind_ret = binding;
|
if (bind_ret) *bind_ret = binding;
|
||||||
|
@ -1321,7 +1328,7 @@ e_bindings_acpi_find(E_Binding_Context ctxt, E_Event_Acpi *ev, E_Binding_Acpi **
|
||||||
/* binding status is set to something, compare event status */
|
/* binding status is set to something, compare event status */
|
||||||
if (binding->status != ev->status) continue;
|
if (binding->status != ev->status) continue;
|
||||||
}
|
}
|
||||||
if (!_e_bindings_context_match(binding->ctxt, ctxt)) continue;
|
if (!e_bindings_context_match(binding->ctxt, ctxt)) continue;
|
||||||
if (act && (binding->ctxt == E_BINDING_CONTEXT_ANY)) continue;
|
if (act && (binding->ctxt == E_BINDING_CONTEXT_ANY)) continue;
|
||||||
act = e_action_find(binding->action);
|
act = e_action_find(binding->action);
|
||||||
if (bind_ret) *bind_ret = binding;
|
if (bind_ret) *bind_ret = binding;
|
||||||
|
@ -1442,8 +1449,8 @@ _e_bindings_acpi_free(E_Binding_Acpi *binding)
|
||||||
E_FREE(binding);
|
E_FREE(binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
E_API int
|
||||||
_e_bindings_context_match(E_Binding_Context bctxt, E_Binding_Context ctxt)
|
e_bindings_context_match(E_Binding_Context bctxt, E_Binding_Context ctxt)
|
||||||
{
|
{
|
||||||
if (bctxt == E_BINDING_CONTEXT_ANY &&
|
if (bctxt == E_BINDING_CONTEXT_ANY &&
|
||||||
!(ctxt == E_BINDING_CONTEXT_ZONE)) return 1;
|
!(ctxt == E_BINDING_CONTEXT_ZONE)) return 1;
|
||||||
|
|
|
@ -202,6 +202,7 @@ E_API void e_bindings_evas_event_mouse_wheel_convert(const Evas_Event_Mouse_Whee
|
||||||
E_API void e_bindings_ecore_event_mouse_button_convert(const Ecore_Event_Mouse_Button *ev, E_Binding_Event_Mouse_Button *event);
|
E_API void e_bindings_ecore_event_mouse_button_convert(const Ecore_Event_Mouse_Button *ev, E_Binding_Event_Mouse_Button *event);
|
||||||
E_API void e_bindings_ecore_event_mouse_wheel_convert(const Ecore_Event_Mouse_Wheel *ev, E_Binding_Event_Wheel *event);
|
E_API void e_bindings_ecore_event_mouse_wheel_convert(const Ecore_Event_Mouse_Wheel *ev, E_Binding_Event_Wheel *event);
|
||||||
|
|
||||||
|
E_API int e_bindings_context_match(E_Binding_Context bctxt, E_Binding_Context ctxt);
|
||||||
|
|
||||||
E_API void e_bindings_disabled_set(Eina_Bool disabled);
|
E_API void e_bindings_disabled_set(Eina_Bool disabled);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -136,6 +136,10 @@ typedef struct E_Comp_Wl_Extension_Data
|
||||||
struct wl_global *global;
|
struct wl_global *global;
|
||||||
Eina_Hash *constraints;
|
Eina_Hash *constraints;
|
||||||
} zwp_pointer_constraints_v1;
|
} zwp_pointer_constraints_v1;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct wl_global *global;
|
||||||
|
} action_route;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
struct wl_global *global;
|
struct wl_global *global;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "xdg-foreign-unstable-v1-server-protocol.h"
|
#include "xdg-foreign-unstable-v1-server-protocol.h"
|
||||||
#include "relative-pointer-unstable-v1-server-protocol.h"
|
#include "relative-pointer-unstable-v1-server-protocol.h"
|
||||||
#include "pointer-constraints-unstable-v1-server-protocol.h"
|
#include "pointer-constraints-unstable-v1-server-protocol.h"
|
||||||
|
#include "action_route-server-protocol.h"
|
||||||
|
|
||||||
|
|
||||||
/* mutter uses 32, seems reasonable */
|
/* mutter uses 32, seems reasonable */
|
||||||
|
@ -569,6 +570,218 @@ _e_comp_wl_zwp_pointer_constraints_v1_confine_pointer(struct wl_client *client,
|
||||||
client, resource, id, surface, pointer, region, lifetime);
|
client, resource, id, surface, pointer, region, lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
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
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
E_Binding_Key key;
|
||||||
|
} binding;
|
||||||
|
uint32_t mode;
|
||||||
|
uint32_t state;
|
||||||
|
struct wl_resource *res;
|
||||||
|
struct wl_resource *surface;
|
||||||
|
} Action_Route;
|
||||||
|
|
||||||
|
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;
|
||||||
|
E_Binding_Key *binding;
|
||||||
|
|
||||||
|
if (bind_ret) *bind_ret = NULL;
|
||||||
|
l = eina_hash_find(key_bindings, ev->key);
|
||||||
|
EINA_LIST_FOREACH(l, ll, ar)
|
||||||
|
{
|
||||||
|
E_Client *ec;
|
||||||
|
|
||||||
|
if (ar->state != ACTION_ROUTE_KEY_GRAB_STATE_ACTIVE) break;
|
||||||
|
binding = &ar->binding.key;
|
||||||
|
if ((!binding->any_mod) && (binding->mod != mod)) continue;
|
||||||
|
if (!e_bindings_context_match(binding->ctxt, ctxt)) continue;
|
||||||
|
ec = wl_resource_get_user_data(ar->surface);
|
||||||
|
if (!ec) continue;//wtf?
|
||||||
|
if (bind_ret) *bind_ret = binding;
|
||||||
|
switch (ar->mode)
|
||||||
|
{
|
||||||
|
/* if exclusive client has grab, activate. otherwise, no actions allowed */
|
||||||
|
case ACTION_ROUTE_MODE_EXCLUSIVE:
|
||||||
|
if (!ec->focused) return NULL;
|
||||||
|
return e_action_find(binding->action);
|
||||||
|
/* all surfaces for wl_client share the grab; if any surface has focus, activate. */
|
||||||
|
case ACTION_ROUTE_MODE_FOCUS_SHARED:
|
||||||
|
{
|
||||||
|
struct wl_client *client;
|
||||||
|
|
||||||
|
client = wl_resource_get_client(ar->surface);
|
||||||
|
if (!e_client_focused_get()) continue;
|
||||||
|
if (wl_resource_get_client(e_client_focused_get()->comp_data->surface) != client)
|
||||||
|
continue;
|
||||||
|
return e_action_find(binding->action);
|
||||||
|
}
|
||||||
|
/* only activate if surface has focus and is on top */
|
||||||
|
case ACTION_ROUTE_MODE_FOCUS_TOPMOST:
|
||||||
|
if (!ec->focused) continue;
|
||||||
|
{
|
||||||
|
E_Client *aec;
|
||||||
|
Eina_Bool valid = EINA_TRUE;
|
||||||
|
|
||||||
|
for (aec = e_client_above_get(ec); aec; aec = e_client_above_get(aec))
|
||||||
|
{
|
||||||
|
if (aec->layer > E_LAYER_CLIENT_PRIO)
|
||||||
|
return e_action_find(binding->action);
|
||||||
|
if (evas_object_visible_get(aec->frame))
|
||||||
|
{
|
||||||
|
valid = EINA_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (valid)
|
||||||
|
return e_action_find(binding->action);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bind_ret) *bind_ret = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_action_route_is_allowed(const char *action, const char *params)
|
||||||
|
{
|
||||||
|
/* FIXME: allow 1-2 bindings maybe */
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_action_route_can_override(const E_Binding_Key *binding)
|
||||||
|
{
|
||||||
|
if (!binding) return EINA_TRUE;
|
||||||
|
/* FIXME: determine full list of overridable binding contexts */
|
||||||
|
if ((binding->ctxt == E_BINDING_CONTEXT_ANY) ||
|
||||||
|
(binding->ctxt == E_BINDING_CONTEXT_WINLIST))
|
||||||
|
return EINA_TRUE;
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_comp_wl_action_route_grab_del(struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
Eina_List *l, *ll;
|
||||||
|
Action_Route *ar;
|
||||||
|
Eina_Bool update;
|
||||||
|
|
||||||
|
/* FIXME: delete active actions? */
|
||||||
|
ar = wl_resource_get_user_data(resource);
|
||||||
|
if (!ar) return;
|
||||||
|
eina_hash_list_remove(key_bindings, ar->binding.key.key, ar);
|
||||||
|
update = (ar->mode == ACTION_ROUTE_MODE_EXCLUSIVE) && (ar->state == ACTION_ROUTE_KEY_GRAB_STATE_ACTIVE);
|
||||||
|
l = eina_hash_find(key_bindings, ar->binding.key.key);
|
||||||
|
eina_stringshare_del(ar->binding.key.key);
|
||||||
|
eina_stringshare_del(ar->binding.key.action);
|
||||||
|
eina_stringshare_del(ar->binding.key.params);
|
||||||
|
free(ar);
|
||||||
|
if (!update) return;
|
||||||
|
EINA_LIST_FOREACH(l, ll, ar)
|
||||||
|
{
|
||||||
|
/* all action routes are active until an exclusive or active grab has been reached */
|
||||||
|
if (ar->state == ACTION_ROUTE_KEY_GRAB_STATE_ACTIVE) break;//futureproofing...
|
||||||
|
ar->state = ACTION_ROUTE_KEY_GRAB_STATE_ACTIVE;
|
||||||
|
action_route_key_grab_send_status(ar->res, ar->state);
|
||||||
|
if (ar->mode == ACTION_ROUTE_MODE_EXCLUSIVE) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_comp_wl_action_route_grab_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
_e_comp_wl_action_route_grab_del(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct action_route_key_grab_interface _e_action_route_grab_interface =
|
||||||
|
{
|
||||||
|
_e_comp_wl_action_route_grab_destroy,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_comp_wl_action_route_grab_key(struct wl_client *client, struct wl_resource *resource EINA_UNUSED,
|
||||||
|
uint32_t id,
|
||||||
|
struct wl_resource *surface,
|
||||||
|
const char *key,
|
||||||
|
uint32_t mode,
|
||||||
|
uint32_t modifiers,
|
||||||
|
const char *action,
|
||||||
|
const char *params)
|
||||||
|
{
|
||||||
|
struct wl_resource *rt;
|
||||||
|
E_Binding_Key *binding;
|
||||||
|
Eina_List *l, *ll;
|
||||||
|
Action_Route *ar, *lar;
|
||||||
|
E_Binding_Context ctxt = E_BINDING_CONTEXT_WINDOW;
|
||||||
|
|
||||||
|
rt = wl_resource_create(client, &action_route_key_grab_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_grab_interface, NULL,
|
||||||
|
_e_comp_wl_action_route_grab_del);
|
||||||
|
binding = e_bindings_key_find(key, modifiers, 0);
|
||||||
|
if ((!_action_route_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->mode = mode;
|
||||||
|
ar->res = rt;
|
||||||
|
ar->surface = surface;
|
||||||
|
binding = &ar->binding.key;
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case ACTION_ROUTE_MODE_EXCLUSIVE:
|
||||||
|
ctxt = E_BINDING_CONTEXT_ANY;
|
||||||
|
break;
|
||||||
|
case ACTION_ROUTE_MODE_FOCUS_SHARED:
|
||||||
|
ctxt = E_BINDING_CONTEXT_WINDOW;
|
||||||
|
break;
|
||||||
|
case ACTION_ROUTE_MODE_FOCUS_TOPMOST:
|
||||||
|
ctxt = E_BINDING_CONTEXT_WINDOW;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
binding->ctxt = ctxt;
|
||||||
|
binding->key = eina_stringshare_add(key);
|
||||||
|
binding->mod = modifiers;
|
||||||
|
binding->any_mod = 0;
|
||||||
|
binding->action = eina_stringshare_add(action);
|
||||||
|
binding->params = eina_stringshare_add(params);
|
||||||
|
wl_resource_set_user_data(rt, ar);
|
||||||
|
l = eina_hash_find(key_bindings, key);
|
||||||
|
EINA_LIST_FOREACH(l, ll, lar)
|
||||||
|
{
|
||||||
|
if (lar->mode == ACTION_ROUTE_MODE_EXCLUSIVE)
|
||||||
|
{
|
||||||
|
ar->state = ACTION_ROUTE_KEY_GRAB_STATE_QUEUED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ar->state = ACTION_ROUTE_KEY_GRAB_STATE_ACTIVE;
|
||||||
|
if (ar->mode == ACTION_ROUTE_MODE_EXCLUSIVE)
|
||||||
|
l = eina_list_prepend_relative(l, ar, ll);
|
||||||
|
else
|
||||||
|
l = eina_list_append(l, ar);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
eina_hash_set(key_bindings, key, l);
|
||||||
|
action_route_key_grab_send_status(ar->res, ar->state);
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static const struct zwp_e_session_recovery_interface _e_session_recovery_interface =
|
static const struct zwp_e_session_recovery_interface _e_session_recovery_interface =
|
||||||
|
@ -608,6 +821,11 @@ static const struct zwp_pointer_constraints_v1_interface _e_zwp_pointer_constrai
|
||||||
_e_comp_wl_zwp_pointer_constraints_v1_confine_pointer,
|
_e_comp_wl_zwp_pointer_constraints_v1_confine_pointer,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct action_route_interface _e_action_route_interface =
|
||||||
|
{
|
||||||
|
_e_comp_wl_action_route_grab_key,
|
||||||
|
};
|
||||||
|
|
||||||
#define GLOBAL_BIND_CB(NAME, IFACE, ...) \
|
#define GLOBAL_BIND_CB(NAME, IFACE, ...) \
|
||||||
static void \
|
static void \
|
||||||
_e_comp_wl_##NAME##_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version EINA_UNUSED, uint32_t id) \
|
_e_comp_wl_##NAME##_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version EINA_UNUSED, uint32_t id) \
|
||||||
|
@ -622,6 +840,7 @@ _e_comp_wl_##NAME##_cb_bind(struct wl_client *client, void *data EINA_UNUSED, ui
|
||||||
}\
|
}\
|
||||||
\
|
\
|
||||||
wl_resource_set_implementation(res, &_e_##NAME##_interface, NULL, NULL);\
|
wl_resource_set_implementation(res, &_e_##NAME##_interface, NULL, NULL);\
|
||||||
|
__VA_ARGS__ \
|
||||||
}
|
}
|
||||||
|
|
||||||
GLOBAL_BIND_CB(session_recovery, zwp_e_session_recovery_interface)
|
GLOBAL_BIND_CB(session_recovery, zwp_e_session_recovery_interface)
|
||||||
|
@ -630,6 +849,10 @@ GLOBAL_BIND_CB(zxdg_exporter_v1, zxdg_exporter_v1_interface)
|
||||||
GLOBAL_BIND_CB(zxdg_importer_v1, zxdg_importer_v1_interface)
|
GLOBAL_BIND_CB(zxdg_importer_v1, zxdg_importer_v1_interface)
|
||||||
GLOBAL_BIND_CB(zwp_relative_pointer_manager_v1, zwp_relative_pointer_manager_v1_interface)
|
GLOBAL_BIND_CB(zwp_relative_pointer_manager_v1, zwp_relative_pointer_manager_v1_interface)
|
||||||
GLOBAL_BIND_CB(zwp_pointer_constraints_v1, zwp_pointer_constraints_v1_interface)
|
GLOBAL_BIND_CB(zwp_pointer_constraints_v1, zwp_pointer_constraints_v1_interface)
|
||||||
|
GLOBAL_BIND_CB(action_route, action_route_interface,
|
||||||
|
e_binding_key_list_cb = _action_route_key_list_cb;
|
||||||
|
key_bindings = eina_hash_string_superfast_new(NULL);
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
#define GLOBAL_CREATE_OR_RETURN(NAME, IFACE, VERSION) \
|
#define GLOBAL_CREATE_OR_RETURN(NAME, IFACE, VERSION) \
|
||||||
|
@ -678,6 +901,7 @@ e_comp_wl_extensions_init(void)
|
||||||
GLOBAL_CREATE_OR_RETURN(zwp_relative_pointer_manager_v1, zwp_relative_pointer_manager_v1_interface, 1);
|
GLOBAL_CREATE_OR_RETURN(zwp_relative_pointer_manager_v1, zwp_relative_pointer_manager_v1_interface, 1);
|
||||||
GLOBAL_CREATE_OR_RETURN(zwp_pointer_constraints_v1, zwp_pointer_constraints_v1_interface, 1);
|
GLOBAL_CREATE_OR_RETURN(zwp_pointer_constraints_v1, zwp_pointer_constraints_v1_interface, 1);
|
||||||
e_comp_wl->extensions->zwp_pointer_constraints_v1.constraints = eina_hash_pointer_new(NULL);
|
e_comp_wl->extensions->zwp_pointer_constraints_v1.constraints = eina_hash_pointer_new(NULL);
|
||||||
|
GLOBAL_CREATE_OR_RETURN(action_route, action_route_interface, 1);
|
||||||
|
|
||||||
ecore_event_handler_add(ECORE_WL2_EVENT_SYNC_DONE, _dmabuf_add, NULL);
|
ecore_event_handler_add(ECORE_WL2_EVENT_SYNC_DONE, _dmabuf_add, NULL);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ protos = [
|
||||||
'../../protocol/session-recovery.xml',
|
'../../protocol/session-recovery.xml',
|
||||||
'../../protocol/www.xml',
|
'../../protocol/www.xml',
|
||||||
'../../protocol/efl-aux-hints.xml',
|
'../../protocol/efl-aux-hints.xml',
|
||||||
|
'../../protocol/action_route.xml',
|
||||||
'@0@/unstable/xdg-foreign/xdg-foreign-unstable-v1.xml'.format(dir_wayland_protocols),
|
'@0@/unstable/xdg-foreign/xdg-foreign-unstable-v1.xml'.format(dir_wayland_protocols),
|
||||||
'@0@/unstable/relative-pointer/relative-pointer-unstable-v1.xml'.format(dir_wayland_protocols),
|
'@0@/unstable/relative-pointer/relative-pointer-unstable-v1.xml'.format(dir_wayland_protocols),
|
||||||
'@0@/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'.format(dir_wayland_protocols),
|
'@0@/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'.format(dir_wayland_protocols),
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
<protocol name="zwp_action_route">
|
||||||
|
<interface name="action_route" version="1">
|
||||||
|
<enum name="mode">
|
||||||
|
<description summary="types of state on the surface">
|
||||||
|
</description>
|
||||||
|
<entry name="focus_shared" value="1" summary="Activatable by any surface if its wl_client has focus">
|
||||||
|
</entry>
|
||||||
|
<entry name="focus_topmost" value="2" summary="Activatable by topmost surface with focus">
|
||||||
|
<description summary="Restricts activation to only the top-most client"/>
|
||||||
|
</entry>
|
||||||
|
<entry name="exclusive" value="3" summary="Activatable by one surface at any time">
|
||||||
|
<description summary="Allows activation for exactly one client at all times"/>
|
||||||
|
</entry>
|
||||||
|
</enum>
|
||||||
|
<enum name="modifiers">
|
||||||
|
<entry name="shift" value="1"></entry>
|
||||||
|
<entry name="control" value="2"></entry>
|
||||||
|
<entry name="alt" value="4"></entry>
|
||||||
|
<entry name="win" value="8"></entry>
|
||||||
|
<entry name="altgr" value="16"></entry>
|
||||||
|
</enum>
|
||||||
|
<request name="grab_key">
|
||||||
|
<description summary="Request a new grab for a key press">
|
||||||
|
</description>
|
||||||
|
<arg name="id" type="new_id" interface="action_route_key_grab"/>
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"/>
|
||||||
|
<arg name="key" type="string"/>
|
||||||
|
<arg name="mode" type="uint"/>
|
||||||
|
<arg name="modifiers" type="uint"/>
|
||||||
|
<arg name="action" type="string"/>
|
||||||
|
<arg name="params" type="string"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
<interface name="action_route_key_grab" 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 grab request"></description>
|
||||||
|
<arg name="state" type="uint"/>
|
||||||
|
</event>
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="Destroy a requested grab">
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
</protocol>
|
Loading…
Reference in New Issue