static void _e_wl_shell_shell_surface_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED);
static int _e_wl_shell_shell_surface_cb_ping_timeout(void *data);
static void _e_wl_shell_shell_surface_cb_render_post(void *data, Evas *evas EINA_UNUSED, void *event EINA_UNUSED);
+static void _e_wl_shell_shell_surface_cb_focus_in(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED);
+static void _e_wl_shell_shell_surface_cb_focus_out(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED);
+static void _e_wl_shell_shell_surface_cb_mouse_in(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED);
+static void _e_wl_shell_shell_surface_cb_mouse_out(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED);
+static void _e_wl_shell_shell_surface_cb_mouse_move(void *data, Evas_Object *obj EINA_UNUSED, void *event);
/* shell surface interface prototypes */
static void _e_wl_shell_shell_surface_cb_pong(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, unsigned int serial);
else
return;
- printf("Configure Surface: %d %d %d %d\n", x, y, w, h);
+ /* printf("Configure Surface: %d %d %d %d\n", x, y, w, h); */
/* handle shell_surface type change */
if ((ewss->next_type != E_WAYLAND_SHELL_SURFACE_TYPE_NONE) &&
evas_object_resize(ews->obj, w, h);
evas_object_show(ews->obj);
+ /* hook smart object callbacks */
+ evas_object_smart_callback_add(ews->obj, "mouse_in",
+ _e_wl_shell_shell_surface_cb_mouse_in, ews);
+ evas_object_smart_callback_add(ews->obj, "mouse_out",
+ _e_wl_shell_shell_surface_cb_mouse_out, ews);
+ evas_object_smart_callback_add(ews->obj, "mouse_move",
+ _e_wl_shell_shell_surface_cb_mouse_move, ews);
+ evas_object_smart_callback_add(ews->obj, "focus_in",
+ _e_wl_shell_shell_surface_cb_focus_in, ews);
+ evas_object_smart_callback_add(ews->obj, "focus_out",
+ _e_wl_shell_shell_surface_cb_focus_out, ews);
+
/* create the e border for this surface */
ews->bd = e_border_new(con, ecore_evas_window_get(ews->ee), 1, 1);
+ e_surface_border_input_set(ews->obj, ews->bd);
e_border_move_resize(ews->bd, x, y, w, h);
e_border_show(ews->bd);
wl_pointer_set_focus(input->wl.seat.pointer, NULL, 0, 0);
}
- if (ews->obj) evas_object_del(ews->obj);
+ if (ews->obj)
+ {
+ /* delete smart callbacks */
+ evas_object_smart_callback_del(ews->obj, "mouse_in",
+ _e_wl_shell_shell_surface_cb_mouse_in);
+ evas_object_smart_callback_del(ews->obj, "mouse_out",
+ _e_wl_shell_shell_surface_cb_mouse_out);
+ evas_object_smart_callback_del(ews->obj, "mouse_move",
+ _e_wl_shell_shell_surface_cb_mouse_move);
+ evas_object_smart_callback_del(ews->obj, "focus_in",
+ _e_wl_shell_shell_surface_cb_focus_in);
+ evas_object_smart_callback_del(ews->obj, "focus_out",
+ _e_wl_shell_shell_surface_cb_focus_out);
+
+ /* delete the object */
+ evas_object_del(ews->obj);
+ }
+
if (ews->ee) ecore_evas_free(ews->ee);
if (ews->bd) e_object_del(E_OBJECT(ews->bd));
}
}
+static void
+_e_wl_shell_shell_surface_cb_focus_in(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+ E_Wayland_Surface *ews = NULL;
+ E_Wayland_Input *input = NULL;
+ Eina_List *l = NULL;
+
+ /* try to cast data to our surface structure */
+ if (!(ews = data)) return;
+
+ /* if this surface is not visible, get out */
+ if (!ews->mapped) return;
+
+ /* loop the list of inputs */
+ EINA_LIST_FOREACH(_e_wl_comp->seats, l, input)
+ {
+ /* set keyboard focus */
+ wl_keyboard_set_focus(input->wl.seat.keyboard, &ews->wl.surface);
+
+ /* update the keyboard focus in the data device */
+ wl_data_device_set_keyboard_focus(&input->wl.seat);
+ }
+}
+
+static void
+_e_wl_shell_shell_surface_cb_focus_out(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+ E_Wayland_Surface *ews = NULL;
+ E_Wayland_Input *input = NULL;
+ Eina_List *l = NULL;
+
+ /* try to cast data to our surface structure */
+ if (!(ews = data)) return;
+
+ /* if this surface is not visible, get out */
+ if (!ews->mapped) return;
+
+ /* loop the list of inputs */
+ EINA_LIST_FOREACH(_e_wl_comp->seats, l, input)
+ {
+ /* set keyboard focus */
+ wl_keyboard_set_focus(input->wl.seat.keyboard, NULL);
+
+ /* end any keyboard grabs */
+ wl_keyboard_end_grab(input->wl.seat.keyboard);
+ }
+}
+
+static void
+_e_wl_shell_shell_surface_cb_mouse_in(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+ E_Wayland_Surface *ews = NULL;
+ struct wl_pointer *ptr = NULL;
+
+ /* try to cast data to our surface structure */
+ if (!(ews = data)) return;
+
+ /* if this surface is not visible, get out */
+ if (!ews->mapped) return;
+
+ /* if (!ews->input) return; */
+
+ /* try to get the pointer from this input */
+ if ((ptr = _e_wl_comp->input->wl.seat.pointer))
+// if ((ptr = ews->input->wl.seat.pointer))
+ {
+ /* if the mouse entered this surface and it is not the current surface */
+ if (&ews->wl.surface != ptr->current)
+ {
+ const struct wl_pointer_grab_interface *grab;
+
+ /* set this surface as the current */
+ grab = ptr->grab->interface;
+ ptr->current = &ews->wl.surface;
+
+ /* send a pointer focus event */
+ grab->focus(ptr->grab, &ews->wl.surface,
+ ptr->current_x, ptr->current_y);
+ }
+ }
+}
+
+static void
+_e_wl_shell_shell_surface_cb_mouse_out(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+ E_Wayland_Surface *ews = NULL;
+ struct wl_pointer *ptr = NULL;
+
+ /* try to cast data to our surface structure */
+ if (!(ews = data)) return;
+
+ /* if (!ews->input) return; */
+
+ /* try to get the pointer from this input */
+ if ((ptr = _e_wl_comp->input->wl.seat.pointer))
+// if ((ptr = ews->input->wl.seat.pointer))
+ {
+ /* if we have a pointer grab and this is the currently focused surface */
+ if ((ptr->grab) && (ptr->focus == ptr->current))
+ return;
+
+ /* set pointer focus */
+ ptr->current = NULL;
+
+ /* NB: Ideally, we should call this function to tell the
+ * pointer that nothing has focus, HOWEVER, when we do
+ * it breaks re-entrant focus of some wayland clients:
+ *
+ * NB: I sent a patch for this already to the wayland devs */
+ wl_pointer_set_focus(ptr, NULL, 0, 0);
+ }
+}
+
+static void
+_e_wl_shell_shell_surface_cb_mouse_move(void *data, Evas_Object *obj EINA_UNUSED, void *event)
+{
+ E_Wayland_Surface *ews = NULL;
+ Evas_Event_Mouse_Move *ev;
+ struct wl_pointer *ptr = NULL;
+
+ ev = event;
+
+ /* try to cast data to our surface structure */
+ if (!(ews = data)) return;
+
+ /* try to get the pointer from this input */
+ if ((ptr = _e_wl_comp->input->wl.seat.pointer))
+// if ((ptr = ews->input->wl.seat.pointer))
+ {
+ ptr->x = wl_fixed_from_int(ev->cur.output.x);
+ ptr->y = wl_fixed_from_int(ev->cur.output.y);
+
+ ptr->current_x = ptr->x;
+ ptr->current_y = ptr->y;
+ ptr->grab->x = ptr->x;
+ ptr->grab->y = ptr->y;
+
+ /* send this mouse movement to wayland */
+ ptr->grab->interface->motion(ptr->grab, ev->timestamp,
+ ptr->grab->x, ptr->grab->y);
+ }
+}
+
/* shell surface interface functions */
static void
_e_wl_shell_shell_surface_cb_pong(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, unsigned int serial)
ecore_evas_name_class_set(ews->ee, ewss->title, ewss->clas);
}
}
-