summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuilherme Iscaro <iscaro@profusion.mobi>2016-11-10 16:06:42 -0200
committerGuilherme Iscaro <iscaro@profusion.mobi>2016-11-10 18:37:02 -0200
commit09ebc64cdbac7aedcf2ae52e6add9efde442ddc0 (patch)
tree8a7894f0b6521f47893d8eb67f37a31923b68368
parent45e1ccf312225efad21a616602aedb3f9f0188bf (diff)
downloadefl-devs/iscaro/wayland-fix.tar.gz
Ecore Evas Wayland: Create the devices during Ecore_Evas setup.devs/iscaro/wayland-fix
Summary: When launching an Elementary App using Wayland the elm_config will automatically connect to the Wayland's display server and all events regarding seats are lost, since by the time that Ecore_Evas is created the global events were already dispatched. To fix this problem, everytime an Ecore_Evas is created, the code must check if there are any seat capabilities available, if so, the devices will be created. Subscribers: cedric, jpeg Differential Revision: https://phab.enlightenment.org/D4390
-rw-r--r--src/lib/ecore_wl2/Ecore_Wl2.h33
-rw-r--r--src/lib/ecore_wl2/ecore_wl2_input.c26
-rw-r--r--src/lib/ecore_wl2/ecore_wl2_window.c7
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c143
4 files changed, 186 insertions, 23 deletions
diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h
index 402206cc70..2d3cc16368 100644
--- a/src/lib/ecore_wl2/Ecore_Wl2.h
+++ b/src/lib/ecore_wl2/Ecore_Wl2.h
@@ -54,6 +54,15 @@ typedef enum
ECORE_WL2_DRAG_ACTION_LAST = 5,
} Ecore_Wl2_Drag_Action;
+typedef enum
+{
+ ECORE_WL2_SEAT_CAPABILITIES_NO_SEAT = 0,
+ ECORE_WL2_SEAT_CAPABILITIES_NONE = 1,
+ ECORE_WL2_SEAT_CAPABILITIES_POINTER = 2,
+ ECORE_WL2_SEAT_CAPABILITIES_KEYBOARD = 4,
+ ECORE_WL2_SEAT_CAPABILITIES_TOUCH = 8
+} Ecore_Wl2_Seat_Capabilities;
+
struct _Ecore_Wl2_Event_Connection
{
Ecore_Wl2_Display *display;
@@ -440,6 +449,14 @@ EAPI Eina_Iterator *ecore_wl2_display_globals_get(Ecore_Wl2_Display *display);
EAPI void ecore_wl2_display_screen_size_get(Ecore_Wl2_Display *display, int *w, int *h);
/**
+ * Get all the Ecore_Wl2_Input from the display.
+ * @param display The display
+ * @return A Eina_Iterator of Ecore_Wl2_Input or @c NULL on error
+ * @since 1.19
+ */
+EAPI Eina_Iterator *ecore_wl2_display_inputs_get(Ecore_Wl2_Display *display);
+
+/**
* Find an Ecore_Wl2_Window based on id
*
* @param display The display to search for the window
@@ -887,6 +904,22 @@ EAPI void ecore_wl2_input_ungrab(Ecore_Wl2_Input *input);
EAPI struct wl_seat *ecore_wl2_input_seat_get(Ecore_Wl2_Input *input);
/**
+ * Get the seat capabilities for a given input.
+ *
+ * @param input The input
+ * @since 1.19
+ */
+EAPI Ecore_Wl2_Seat_Capabilities ecore_wl2_input_seat_capabilities_get(Ecore_Wl2_Input *input);
+
+/**
+ * Get the wayland's seat id from an input.
+ * @param input The input
+ * @return The seat id
+ * @since 1.19
+ */
+EAPI unsigned int ecore_wl2_input_seat_id_get(Ecore_Wl2_Input *input);
+
+/**
* @defgroup Ecore_Wl2_Dnd_Group Wayland Library Drag-n-Drop Functions
* @ingroup Ecore_Wl2_Group
*
diff --git a/src/lib/ecore_wl2/ecore_wl2_input.c b/src/lib/ecore_wl2/ecore_wl2_input.c
index 830c6adbeb..a17c665a0a 100644
--- a/src/lib/ecore_wl2/ecore_wl2_input.c
+++ b/src/lib/ecore_wl2/ecore_wl2_input.c
@@ -1572,3 +1572,29 @@ ecore_wl2_input_seat_get(Ecore_Wl2_Input *input)
return input->wl.seat;
}
+
+EAPI Ecore_Wl2_Seat_Capabilities
+ecore_wl2_input_seat_capabilities_get(Ecore_Wl2_Input *input)
+{
+
+ Ecore_Wl2_Seat_Capabilities cap = ECORE_WL2_SEAT_CAPABILITIES_NONE;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(input, ECORE_WL2_SEAT_CAPABILITIES_NO_SEAT);
+
+ if (!input->wl.seat)
+ return ECORE_WL2_SEAT_CAPABILITIES_NO_SEAT;
+ if (input->wl.keyboard)
+ cap |= ECORE_WL2_SEAT_CAPABILITIES_KEYBOARD;
+ if (input->wl.pointer)
+ cap |= ECORE_WL2_SEAT_CAPABILITIES_POINTER;
+ if (input->wl.touch)
+ cap |= ECORE_WL2_SEAT_CAPABILITIES_TOUCH;
+ return cap;
+}
+
+EAPI unsigned int
+ecore_wl2_input_seat_id_get(Ecore_Wl2_Input *input)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(input, 0);
+ return input->id;
+}
diff --git a/src/lib/ecore_wl2/ecore_wl2_window.c b/src/lib/ecore_wl2/ecore_wl2_window.c
index b2aa63f005..2c19f05ec1 100644
--- a/src/lib/ecore_wl2/ecore_wl2_window.c
+++ b/src/lib/ecore_wl2/ecore_wl2_window.c
@@ -993,6 +993,13 @@ ecore_wl2_window_input_get(Ecore_Wl2_Window *window)
return NULL;
}
+EAPI Eina_Iterator *
+ecore_wl2_display_inputs_get(Ecore_Wl2_Display *display)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
+ return eina_inlist_iterator_new(display->inputs);
+}
+
EAPI Eina_Bool
ecore_wl2_window_has_shell_surface(Ecore_Wl2_Window *window)
{
diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
index db60d98a23..9184c6c384 100644
--- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
+++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
@@ -516,11 +516,43 @@ _ecore_evas_wl_common_device_event_add(int event_type, Ecore_Wl2_Device_Type dev
dev);
}
+static EE_Wl_Device *
+_ecore_evas_wl_common_seat_add(Ecore_Evas *ee,
+ const char *seat_name,
+ unsigned int id)
+{
+ Ecore_Evas_Engine_Wl_Data *wdata;
+ EE_Wl_Device *device;
+ Evas_Device *dev;
+
+ device = calloc(1, sizeof(EE_Wl_Device));
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, NULL);
+
+ dev = evas_device_add_full(ee->evas, seat_name, "Wayland seat",
+ NULL, NULL,
+ EVAS_DEVICE_CLASS_SEAT,
+ EVAS_DEVICE_SUBCLASS_NONE);
+ EINA_SAFETY_ON_NULL_GOTO(dev, err_dev);
+
+ device->seat = dev;
+ device->id = id;
+
+ wdata = ee->engine.data;
+ wdata->devices_list = eina_list_append(wdata->devices_list, device);
+
+ _ecore_evas_wl_common_device_event_add(ECORE_WL2_EVENT_DEVICE_ADDED,
+ ECORE_WL2_DEVICE_TYPE_SEAT,
+ id, dev, ee);
+ return device;
+ err_dev:
+ free(device);
+ return NULL;
+}
+
static Eina_Bool
_ecore_evas_wl_common_cb_global_added(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
{
Ecore_Wl2_Event_Global *ev = event;
- EE_Wl_Device *device;
Ecore_Evas *ee;
Eina_List *l;
char buf[32];
@@ -532,34 +564,27 @@ _ecore_evas_wl_common_cb_global_added(void *d EINA_UNUSED, int t EINA_UNUSED, vo
EINA_LIST_FOREACH(ee_list, l, ee)
{
- Ecore_Evas_Engine_Wl_Data *wdata;
- Evas_Device *dev;
-
- device = calloc(1, sizeof(EE_Wl_Device));
- EINA_SAFETY_ON_NULL_GOTO(device, err_device);
-
- dev = evas_device_add_full(ee->evas, buf, "Wayland seat",
- NULL, NULL,
- EVAS_DEVICE_CLASS_SEAT,
- EVAS_DEVICE_SUBCLASS_NONE);
- EINA_SAFETY_ON_NULL_GOTO(dev, err_dev);
-
- device->seat = dev;
- device->id = ev->id;
+ Eina_List *ll;
+ EE_Wl_Device *device;
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+ Eina_Bool already_present = EINA_FALSE;
- wdata = ee->engine.data;
- wdata->devices_list = eina_list_append(wdata->devices_list, device);
+ EINA_LIST_FOREACH(wdata->devices_list, ll, device)
+ {
+ if (device->id == ev->id)
+ {
+ already_present = EINA_TRUE;
+ break;
+ }
+ }
- _ecore_evas_wl_common_device_event_add(ECORE_WL2_EVENT_DEVICE_ADDED,
- ECORE_WL2_DEVICE_TYPE_SEAT,
- ev->id, dev, ee);
+ if (!already_present && !_ecore_evas_wl_common_seat_add(ee, buf, ev->id))
+ goto err_add;
}
return ECORE_CALLBACK_PASS_ON;
-err_dev:
- free(device);
-err_device:
+err_add:
return ECORE_CALLBACK_PASS_ON;
}
@@ -2006,6 +2031,72 @@ _ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
return ECORE_CALLBACK_PASS_ON;
}
+static Eina_Bool
+_ecore_wl2_devices_setup(Ecore_Evas *ee, Ecore_Wl2_Display *display)
+{
+ Eina_Bool r = EINA_TRUE;
+ Ecore_Wl2_Input *input;
+ Eina_Iterator *itr = ecore_wl2_display_inputs_get(display);
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(itr, EINA_FALSE);
+ EINA_ITERATOR_FOREACH(itr, input)
+ {
+ EE_Wl_Device *device;
+ Ecore_Wl2_Seat_Capabilities cap;
+ char buf[32];
+ unsigned int id;
+
+ id = ecore_wl2_input_seat_id_get(input);
+ cap = ecore_wl2_input_seat_capabilities_get(input);
+ //No seat, ignore...
+ if (cap == ECORE_WL2_SEAT_CAPABILITIES_NO_SEAT)
+ continue;
+
+ snprintf(buf, sizeof(buf), "seat-%u", id);
+ device = _ecore_evas_wl_common_seat_add(ee, buf, id);
+ if (!device)
+ {
+ r = EINA_FALSE;
+ break;
+ }
+ if (cap & ECORE_WL2_SEAT_CAPABILITIES_KEYBOARD)
+ {
+ device->keyboard = evas_device_add_full(ee->evas, "Keyboard",
+ "A wayland keyboard device",
+ device->seat, NULL,
+ EVAS_DEVICE_CLASS_KEYBOARD,
+ EVAS_DEVICE_SUBCLASS_NONE);
+ _ecore_evas_wl_common_device_event_add(ECORE_WL2_EVENT_DEVICE_ADDED,
+ ECORE_WL2_DEVICE_TYPE_KEYBOARD,
+ id, device->keyboard, ee);
+ }
+ if (cap & ECORE_WL2_SEAT_CAPABILITIES_POINTER)
+ {
+ device->pointer = evas_device_add_full(ee->evas, "Mouse",
+ "A wayland pointer device",
+ device->seat, NULL,
+ EVAS_DEVICE_CLASS_MOUSE,
+ EVAS_DEVICE_SUBCLASS_NONE);
+ _ecore_evas_wl_common_device_event_add(ECORE_WL2_EVENT_DEVICE_ADDED,
+ ECORE_WL2_DEVICE_TYPE_POINTER,
+ id, device->pointer, ee);
+ }
+ if (cap & ECORE_WL2_SEAT_CAPABILITIES_TOUCH)
+ {
+ device->touch = evas_device_add_full(ee->evas, "Touch",
+ "A wayland touch device",
+ device->seat, NULL,
+ EVAS_DEVICE_CLASS_TOUCH,
+ EVAS_DEVICE_SUBCLASS_NONE);
+ _ecore_evas_wl_common_device_event_add(ECORE_WL2_EVENT_DEVICE_ADDED,
+ ECORE_WL2_DEVICE_TYPE_TOUCH,
+ id, device->touch, ee);
+ }
+ }
+ eina_iterator_free(itr);
+ return r;
+}
+
Ecore_Evas *
_ecore_evas_wl_common_new_internal(const char *disp_name, unsigned int parent, int x, int y, int w, int h, Eina_Bool frame, const char *engine_name)
{
@@ -2146,6 +2237,12 @@ _ecore_evas_wl_common_new_internal(const char *disp_name, unsigned int parent, i
}
}
+ if (!_ecore_wl2_devices_setup(ee, ewd))
+ {
+ ERR("Failed to create the devices");
+ goto eng_err;
+ }
+
ee->engine.func->fn_render = _ecore_evas_wl_common_render;
_ecore_evas_register(ee);