diff --git a/src/bin/Makefile.mk b/src/bin/Makefile.mk index 9c6ea40d1..c7d04fc1e 100644 --- a/src/bin/Makefile.mk +++ b/src/bin/Makefile.mk @@ -395,6 +395,8 @@ endif if HAVE_WAYLAND enlightenment_src += \ src/bin/e_uuid_store.c \ +src/bin/generated/www-protocol.c \ +src/bin/generated/www-protocol.h \ src/bin/generated/session-recovery-protocol.c \ src/bin/generated/session-recovery-server-protocol.h \ src/bin/generated/e_comp_wl_screenshooter_server.c \ diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index af84ef460..84f1066a0 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -5,6 +5,8 @@ #define __STDC_FORMAT_MACROS #include +#include "www-protocol.h" + /* When a wayland is released with this macro we can remove the ifdefs */ #ifdef WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION # define COMPOSITOR_VERSION 4 @@ -581,6 +583,15 @@ _e_comp_wl_evas_cb_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_U Eina_List *l; if (e_object_is_del(E_OBJECT(ec))) return; + if (ec->comp_data->www.surface) + { + if (ec->comp_data->moved && (!ec->maximized) && (!ec->fullscreen)) + www_surface_send_status(ec->comp_data->www.surface, + ec->x - ec->comp_data->www.x, ec->y - ec->comp_data->www.y, lround(ecore_loop_time_get())); + ec->comp_data->www.x = ec->x; + ec->comp_data->www.y = ec->y; + } + ec->comp_data->moved = 1; EINA_LIST_FOREACH(ec->comp_data->sub.list, l, sec) { if (!sec->comp_data->sub.data->position.set) diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h index ac63aa012..d6a52d35c 100644 --- a/src/bin/e_comp_wl.h +++ b/src/bin/e_comp_wl.h @@ -104,6 +104,10 @@ typedef struct E_Comp_Wl_Extension_Data { struct wl_resource *global; } session_recovery; + struct + { + struct wl_resource *global; + } www; } E_Comp_Wl_Extension_Data; struct _E_Comp_Wl_Data @@ -283,6 +287,11 @@ struct _E_Comp_Wl_Client_Data Eina_Rectangle window; E_Shell_Data *data; } shell; + struct + { + struct wl_resource *surface; + int x, y; + } www; E_Comp_Wl_Surface_State pending; @@ -304,6 +313,7 @@ struct _E_Comp_Wl_Client_Data Eina_Bool set_win_type : 1; Eina_Bool frame_update : 1; Eina_Bool cursor : 1; + Eina_Bool moved : 1; }; struct _E_Comp_Wl_Output diff --git a/src/bin/e_comp_wl_extensions.c b/src/bin/e_comp_wl_extensions.c index 57644ac80..b09348e65 100644 --- a/src/bin/e_comp_wl_extensions.c +++ b/src/bin/e_comp_wl_extensions.c @@ -3,6 +3,25 @@ #include "e_comp_wl_screenshooter_server.h" #include "session-recovery-server-protocol.h" +#include "www-protocol.h" + +static void +_e_comp_wl_extensions_client_move_begin(void *d EINA_UNUSED, E_Client *ec) +{ + if (e_client_has_xwindow(ec) || e_object_is_del(E_OBJECT(ec))) return; + + if (ec->comp_data->www.surface) + www_surface_send_start_drag(ec->comp_data->www.surface); +} + +static void +_e_comp_wl_extensions_client_move_end(void *d EINA_UNUSED, E_Client *ec) +{ + if (e_client_has_xwindow(ec) || e_object_is_del(E_OBJECT(ec))) return; + + if (ec->comp_data->www.surface) + www_surface_send_end_drag(ec->comp_data->www.surface); +} static void _e_comp_wl_sr_cb_provide_uuid(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, const char *uuid) @@ -71,6 +90,57 @@ _e_comp_wl_screenshooter_cb_shoot(struct wl_client *client EINA_UNUSED, struct w screenshooter_send_done(resource); } +static void +_e_comp_wl_www_surface_del(struct wl_resource *res) +{ + E_Client *ec; + + ec = wl_resource_get_user_data(res); + if (!e_object_is_del(E_OBJECT(ec))) + ec->comp_data->www.surface = NULL; + e_object_unref(E_OBJECT(ec)); +} + +static void +_e_comp_wl_www_surface_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static const struct www_surface_interface _e_www_surface_interface = +{ + _e_comp_wl_www_surface_destroy, +}; + +static void +_e_comp_wl_www_cb_create(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface) +{ + struct wl_resource *ww; + E_Client *ec; + + ec = wl_resource_get_user_data(surface); + if (ec->comp_data->www.surface) + { + wl_resource_post_error(resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "Surface already created www_surface"); + return; + } + ww = wl_resource_create(client, &www_surface_interface, 1, id); + if (!ww) + { + ERR("Could not create www_surface!"); + wl_client_post_no_memory(client); + return; + } + wl_resource_set_implementation(ww, &_e_www_surface_interface, NULL, _e_comp_wl_www_surface_del); + wl_resource_set_user_data(ww, ec); + ec->comp_data->www.surface = ww; + ec->comp_data->www.x = ec->x; + ec->comp_data->www.y = ec->y; + e_object_ref(E_OBJECT(ec)); +} + static const struct zwp_e_session_recovery_interface _e_session_recovery_interface = { _e_comp_wl_sr_cb_provide_uuid, @@ -81,6 +151,12 @@ static const struct screenshooter_interface _e_screenshooter_interface = _e_comp_wl_screenshooter_cb_shoot }; +static const struct www_interface _e_www_interface = +{ + _e_comp_wl_www_cb_create +}; + + #define GLOBAL_BIND_CB(NAME, IFACE, ...) \ static void \ _e_comp_wl_##NAME##_cb_unbind(struct wl_resource *resource EINA_UNUSED) \ @@ -105,6 +181,7 @@ _e_comp_wl_##NAME##_cb_bind(struct wl_client *client, void *data EINA_UNUSED, ui GLOBAL_BIND_CB(session_recovery, zwp_e_session_recovery_interface) GLOBAL_BIND_CB(screenshooter, screenshooter_interface) +GLOBAL_BIND_CB(www, www_interface) #define GLOBAL_CREATE_OR_RETURN(NAME, IFACE) \ @@ -124,6 +201,10 @@ e_comp_wl_extensions_init(void) /* try to add session_recovery to wayland globals */ GLOBAL_CREATE_OR_RETURN(session_recovery, zwp_e_session_recovery_interface); GLOBAL_CREATE_OR_RETURN(screenshooter, screenshooter_interface); + GLOBAL_CREATE_OR_RETURN(www, www_interface); + + e_client_hook_add(E_CLIENT_HOOK_MOVE_BEGIN, _e_comp_wl_extensions_client_move_begin, NULL); + e_client_hook_add(E_CLIENT_HOOK_MOVE_END, _e_comp_wl_extensions_client_move_end, NULL); e_comp_wl->extensions = E_NEW(E_Comp_Wl_Extension_Data, 1); return EINA_TRUE; diff --git a/src/bin/generated/www-protocol.c b/src/bin/generated/www-protocol.c new file mode 100644 index 000000000..952b333b5 --- /dev/null +++ b/src/bin/generated/www-protocol.c @@ -0,0 +1,41 @@ +#include +#include +#include "wayland-util.h" + +extern const struct wl_interface wl_surface_interface; +extern const struct wl_interface www_surface_interface; + +static const struct wl_interface *types[] = { + NULL, + NULL, + NULL, + &www_surface_interface, + &wl_surface_interface, +}; + +static const struct wl_message www_requests[] = { + { "create", "no", types + 3 }, +}; + +WL_EXPORT const struct wl_interface www_interface = { + "www", 1, + 1, www_requests, + 0, NULL, +}; + +static const struct wl_message www_surface_requests[] = { + { "destroy", "", types + 0 }, +}; + +static const struct wl_message www_surface_events[] = { + { "status", "iiu", types + 0 }, + { "start_drag", "", types + 0 }, + { "end_drag", "", types + 0 }, +}; + +WL_EXPORT const struct wl_interface www_surface_interface = { + "www_surface", 1, + 1, www_surface_requests, + 3, www_surface_events, +}; + diff --git a/src/bin/generated/www-protocol.h b/src/bin/generated/www-protocol.h new file mode 100644 index 000000000..8bd616f48 --- /dev/null +++ b/src/bin/generated/www-protocol.h @@ -0,0 +1,77 @@ +#ifndef ZWP_WWW_SERVER_PROTOCOL_H +#define ZWP_WWW_SERVER_PROTOCOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "wayland-server.h" + +struct wl_client; +struct wl_resource; + +struct wl_surface; +struct www; +struct www_surface; + +extern const struct wl_interface www_interface; +extern const struct wl_interface www_surface_interface; + +struct www_interface { + /** + * create - Create an object for WWW notifications + * @id: (none) + * @surface: (none) + * + * + */ + void (*create)(struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface); +}; + + +struct www_surface_interface { + /** + * destroy - Destroy a www_surface + * + * + */ + void (*destroy)(struct wl_client *client, + struct wl_resource *resource); +}; + +#define WWW_SURFACE_STATUS 0 +#define WWW_SURFACE_START_DRAG 1 +#define WWW_SURFACE_END_DRAG 2 + +#define WWW_SURFACE_STATUS_SINCE_VERSION 1 +#define WWW_SURFACE_START_DRAG_SINCE_VERSION 1 +#define WWW_SURFACE_END_DRAG_SINCE_VERSION 1 + +static inline void +www_surface_send_status(struct wl_resource *resource_, int32_t x_rel, int32_t y_rel, uint32_t timestamp) +{ + wl_resource_post_event(resource_, WWW_SURFACE_STATUS, x_rel, y_rel, timestamp); +} + +static inline void +www_surface_send_start_drag(struct wl_resource *resource_) +{ + wl_resource_post_event(resource_, WWW_SURFACE_START_DRAG); +} + +static inline void +www_surface_send_end_drag(struct wl_resource *resource_) +{ + wl_resource_post_event(resource_, WWW_SURFACE_END_DRAG); +} + +#ifdef __cplusplus +} +#endif + +#endif