elm_win: implement v2 of teamwork api using window-based display protocol

this adds support for wayland and makes teamwork integration trivial for any
application

@feature
This commit is contained in:
Mike Blumenkrantz 2016-05-20 14:04:21 -04:00
parent 9be179d740
commit 7510e42c1b
11 changed files with 356 additions and 2 deletions

View File

@ -8,6 +8,8 @@ installed_ecorewl2mainheadersdir = $(includedir)/ecore-wl2-@VMAJ@
dist_installed_ecorewl2mainheaders_DATA = lib/ecore_wl2/Ecore_Wl2.h
lib_ecore_wl2_libecore_wl2_la_SOURCES = \
lib/ecore_wl2/teamwork_protocol.c \
lib/ecore_wl2/teamwork_protocol.h \
lib/ecore_wl2/session-recovery.h \
lib/ecore_wl2/session-recovery.c \
lib/ecore_wl2/subsurface-client-protocol.h \

View File

@ -641,6 +641,7 @@ lib_elementary_libelementary_la_SOURCES = \
lib/elementary/efl_ui_grid.c \
$(NULL)
lib_elementary_libelementary_la_CFLAGS = @ELEMENTARY_CFLAGS@
lib_elementary_libelementary_la_LIBADD = \
@ELEMENTARY_LIBS@ \

View File

@ -166,6 +166,12 @@ _cb_global_add(void *data, struct wl_registry *registry, unsigned int id, const
wl_registry_bind(registry, id,
&zwp_e_session_recovery_interface, 1);
}
else if (!strcmp(interface, "zwp_teamwork"))
{
ewd->wl.teamwork =
wl_registry_bind(registry, id,
&zwp_teamwork_interface, EFL_TEAMWORK_VERSION);
}
else if (!strcmp(interface, "wl_output"))
_ecore_wl2_output_add(ewd, id);
else if (!strcmp(interface, "wl_seat"))

View File

@ -6,6 +6,9 @@
# include "Ecore_Input.h"
# include "www-protocol.h"
#define EFL_TEAMWORK_VERSION 2
# include "teamwork_protocol.h"
/* NB: Test if subsurface protocol is part of wayland code, if not then
* include our own copy */
# ifndef WL_SUBSURFACE_ERROR_ENUM
@ -84,6 +87,7 @@ struct _Ecore_Wl2_Display
struct xdg_shell *xdg_shell;
struct www *www;
struct zwp_e_session_recovery *session_recovery;
struct zwp_teamwork *teamwork;
int compositor_version;
} wl;

View File

@ -0,0 +1,46 @@
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
extern const struct wl_interface wl_surface_interface;
static const struct wl_interface *types[] = {
&wl_surface_interface,
NULL,
&wl_surface_interface,
NULL,
NULL,
NULL,
&wl_surface_interface,
NULL,
&wl_surface_interface,
NULL,
&wl_surface_interface,
NULL,
&wl_surface_interface,
NULL,
NULL,
&wl_surface_interface,
NULL,
NULL,
};
static const struct wl_message zwp_teamwork_requests[] = {
{ "preload_uri", "os", types + 0 },
{ "activate_uri", "osff", types + 2 },
{ "deactivate_uri", "os", types + 6 },
{ "open_uri", "os", types + 8 },
};
static const struct wl_message zwp_teamwork_events[] = {
{ "fetching_uri", "os", types + 10 },
{ "completed_uri", "osi", types + 12 },
{ "fetch_info", "osu", types + 15 },
};
WL_EXPORT const struct wl_interface zwp_teamwork_interface = {
"zwp_teamwork", 2,
4, zwp_teamwork_requests,
3, zwp_teamwork_events,
};

View File

@ -0,0 +1,128 @@
#ifndef TEAMWORK_CLIENT_PROTOCOL_H
#define TEAMWORK_CLIENT_PROTOCOL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stddef.h>
#include "wayland-client.h"
struct wl_client;
struct wl_resource;
struct wl_surface;
struct zwp_teamwork;
extern const struct wl_interface zwp_teamwork_interface;
struct zwp_teamwork_listener {
/**
* fetching_uri - (none)
* @surface: (none)
* @uri: (none)
*/
void (*fetching_uri)(void *data,
struct zwp_teamwork *zwp_teamwork,
struct wl_surface *surface,
const char *uri);
/**
* completed_uri - (none)
* @surface: (none)
* @uri: (none)
* @valid: 1 if uri can be displayed, else 0
*/
void (*completed_uri)(void *data,
struct zwp_teamwork *zwp_teamwork,
struct wl_surface *surface,
const char *uri,
int32_t valid);
/**
* fetch_info - (none)
* @surface: (none)
* @uri: (none)
* @progress: percentage of download
*/
void (*fetch_info)(void *data,
struct zwp_teamwork *zwp_teamwork,
struct wl_surface *surface,
const char *uri,
uint32_t progress);
};
static inline int
zwp_teamwork_add_listener(struct zwp_teamwork *zwp_teamwork,
const struct zwp_teamwork_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *) zwp_teamwork,
(void (**)(void)) listener, data);
}
#define ZWP_TEAMWORK_PRELOAD_URI 0
#define ZWP_TEAMWORK_ACTIVATE_URI 1
#define ZWP_TEAMWORK_DEACTIVATE_URI 2
#define ZWP_TEAMWORK_OPEN_URI 3
#define ZWP_TEAMWORK_PRELOAD_URI_SINCE_VERSION 1
#define ZWP_TEAMWORK_ACTIVATE_URI_SINCE_VERSION 1
#define ZWP_TEAMWORK_DEACTIVATE_URI_SINCE_VERSION 1
#define ZWP_TEAMWORK_OPEN_URI_SINCE_VERSION 1
static inline void
zwp_teamwork_set_user_data(struct zwp_teamwork *zwp_teamwork, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) zwp_teamwork, user_data);
}
static inline void *
zwp_teamwork_get_user_data(struct zwp_teamwork *zwp_teamwork)
{
return wl_proxy_get_user_data((struct wl_proxy *) zwp_teamwork);
}
static inline uint32_t
zwp_teamwork_get_version(struct zwp_teamwork *zwp_teamwork)
{
return wl_proxy_get_version((struct wl_proxy *) zwp_teamwork);
}
static inline void
zwp_teamwork_destroy(struct zwp_teamwork *zwp_teamwork)
{
wl_proxy_destroy((struct wl_proxy *) zwp_teamwork);
}
static inline void
zwp_teamwork_preload_uri(struct zwp_teamwork *zwp_teamwork, struct wl_surface *surface, const char *uri)
{
wl_proxy_marshal((struct wl_proxy *) zwp_teamwork,
ZWP_TEAMWORK_PRELOAD_URI, surface, uri);
}
static inline void
zwp_teamwork_activate_uri(struct zwp_teamwork *zwp_teamwork, struct wl_surface *surface, const char *uri, wl_fixed_t x, wl_fixed_t y)
{
wl_proxy_marshal((struct wl_proxy *) zwp_teamwork,
ZWP_TEAMWORK_ACTIVATE_URI, surface, uri, x, y);
}
static inline void
zwp_teamwork_deactivate_uri(struct zwp_teamwork *zwp_teamwork, struct wl_surface *surface, const char *uri)
{
wl_proxy_marshal((struct wl_proxy *) zwp_teamwork,
ZWP_TEAMWORK_DEACTIVATE_URI, surface, uri);
}
static inline void
zwp_teamwork_open_uri(struct zwp_teamwork *zwp_teamwork, struct wl_surface *surface, const char *uri)
{
wl_proxy_marshal((struct wl_proxy *) zwp_teamwork,
ZWP_TEAMWORK_OPEN_URI, surface, uri);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -337,4 +337,15 @@ EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_AUX_HINT_ALLOWED; /**< @since 1.1
/* E keyrouter protocol */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_KEYROUTER_SUPPORTED; /**< @since 1.15 */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_KEYROUTER_WINDOW_KEYTABLE; /**< @since 1.15 */
/* Teamwork protocol */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_PROPERTY; /**< @since 1.18 */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_PRELOAD; /**< @since 1.18 */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_ACTIVATE; /**< @since 1.18 */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_DEACTIVATE; /**< @since 1.18 */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_OPEN; /**< @since 1.18 */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_COMPLETED; /**< @since 1.18 */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_PROGRESS; /**< @since 1.18 */
EAPI extern Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_STARTED; /**< @since 1.18 */
#endif /* _ECORE_X_ATOMS_H */

View File

@ -367,6 +367,17 @@ EAPI Ecore_X_Atom ECORE_X_ATOM_E_WINDOW_AUX_HINT_ALLOWED = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_E_KEYROUTER_SUPPORTED = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_E_KEYROUTER_WINDOW_KEYTABLE = 0;
/* Teamwork protocol */
EAPI Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_PROPERTY = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_PRELOAD = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_ACTIVATE = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_DEACTIVATE = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_OPEN = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_COMPLETED = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_PROGRESS = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_TEAMWORK_STARTED = 0;
typedef struct _Atom_Item Atom_Item;
struct _Atom_Item
@ -684,6 +695,16 @@ const Atom_Item atom_items[] =
{ "_E_WINDOW_AUX_HINT_SUPPORTED_LIST", &ECORE_X_ATOM_E_WINDOW_AUX_HINT_SUPPORTED_LIST },
{ "_E_WINDOW_AUX_HINT_SUPPORT", &ECORE_X_ATOM_E_WINDOW_AUX_HINT_SUPPORT },
{ "_E_WINDOW_AUX_HINT", &ECORE_X_ATOM_E_WINDOW_AUX_HINT },
{ "_E_WINDOW_AUX_HINT_ALLOWED", &ECORE_X_ATOM_E_WINDOW_AUX_HINT_ALLOWED }
{ "_E_WINDOW_AUX_HINT_ALLOWED", &ECORE_X_ATOM_E_WINDOW_AUX_HINT_ALLOWED },
{ "_TEAMWORK_PROP", &ECORE_X_ATOM_TEAMWORK_PROPERTY },
{ "_TEAMWORK_PRELOAD", &ECORE_X_ATOM_TEAMWORK_PRELOAD },
{ "_TEAMWORK_ACTIVATE", &ECORE_X_ATOM_TEAMWORK_ACTIVATE },
{ "_TEAMWORK_DEACTIVATE", &ECORE_X_ATOM_TEAMWORK_DEACTIVATE },
{ "_TEAMWORK_OPEN", &ECORE_X_ATOM_TEAMWORK_OPEN },
{ "_TEAMWORK_COMPLETED", &ECORE_X_ATOM_TEAMWORK_COMPLETED },
{ "_TEAMWORK_PROGRESS", &ECORE_X_ATOM_TEAMWORK_PROGRESS },
{ "_TEAMWORK_STARTED", &ECORE_X_ATOM_TEAMWORK_STARTED },
};

View File

@ -134,6 +134,7 @@ struct _Elm_Win_Data
Ecore_Win32_Window *win;
} win32;
#endif
Eina_Stringshare *teamwork_uri;
Eina_Bool deferred_resize_job;
Ecore_Job *deferred_child_eval_job;
@ -2013,6 +2014,7 @@ _elm_win_evas_object_smart_del(Eo *obj, Elm_Win_Data *sd)
ecore_job_del(sd->deferred_child_eval_job);
eina_stringshare_del(sd->shot.info);
ecore_timer_del(sd->shot.timer);
eina_stringshare_replace(&sd->teamwork_uri, NULL);
#ifdef HAVE_ELEMENTARY_X
ecore_event_handler_del(sd->x.client_message_handler);
@ -6012,4 +6014,100 @@ elm_win_quickpanel_zone_get(const Evas_Object *obj)
return 0;
}
static EOLIAN void
_elm_win_teamwork_uri_preload(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *uri)
{
#ifdef HAVE_ELEMENTARY_X
if (sd->x.xwin)
{
ecore_x_window_prop_string_set(sd->x.xwin, ECORE_X_ATOM_TEAMWORK_PROPERTY, uri);
ecore_x_client_message32_send(sd->x.xwin, ECORE_X_ATOM_TEAMWORK_PRELOAD,
ECORE_X_EVENT_MASK_WINDOW_MANAGE | ECORE_X_EVENT_MASK_WINDOW_CHILD_CONFIGURE, EFL_TEAMWORK_VERSION, 0, 0, 0, 0);
}
#endif
#ifdef HAVE_ELEMENTARY_WL2
if (sd->wl.win)
{
Ecore_Wl2_Display *ewd = ecore_wl2_window_display_get(sd->wl.win);
if (ewd->wl.teamwork)
zwp_teamwork_preload_uri(ewd->wl.teamwork, ecore_wl2_window_surface_get(sd->wl.win), uri);
}
#endif
eina_stringshare_replace(&sd->teamwork_uri, uri);
}
static EOLIAN void
_elm_win_teamwork_uri_show(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *uri)
{
int x, y;
EINA_SAFETY_ON_NULL_RETURN(uri);
if (eina_streq(uri, sd->teamwork_uri)) return;
evas_pointer_canvas_xy_get(sd->evas, &x, &y);
#ifdef HAVE_ELEMENTARY_X
if (sd->x.xwin)
{
ecore_x_window_prop_string_set(sd->x.xwin, ECORE_X_ATOM_TEAMWORK_PROPERTY, uri);
ecore_x_client_message32_send(sd->x.xwin, ECORE_X_ATOM_TEAMWORK_ACTIVATE,
ECORE_X_EVENT_MASK_WINDOW_MANAGE | ECORE_X_EVENT_MASK_WINDOW_CHILD_CONFIGURE, EFL_TEAMWORK_VERSION, x, y, 0, 0);
}
#endif
#ifdef HAVE_ELEMENTARY_WL2
if (sd->wl.win)
{
Ecore_Wl2_Display *ewd = ecore_wl2_window_display_get(sd->wl.win);
if (ewd->wl.teamwork)
zwp_teamwork_activate_uri(ewd->wl.teamwork, ecore_wl2_window_surface_get(sd->wl.win),
uri, wl_fixed_from_int(x), wl_fixed_from_int(y));
}
#endif
eina_stringshare_replace(&sd->teamwork_uri, uri);
}
static EOLIAN void
_elm_win_teamwork_uri_hide(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
{
if (!sd->teamwork_uri) return;
#ifdef HAVE_ELEMENTARY_X
if (sd->x.xwin)
{
ecore_x_window_prop_string_set(sd->x.xwin, ECORE_X_ATOM_TEAMWORK_PROPERTY, sd->teamwork_uri);
ecore_x_client_message32_send(sd->x.xwin, ECORE_X_ATOM_TEAMWORK_DEACTIVATE,
ECORE_X_EVENT_MASK_WINDOW_MANAGE | ECORE_X_EVENT_MASK_WINDOW_CHILD_CONFIGURE, EFL_TEAMWORK_VERSION, 0, 0, 0, 0);
}
#endif
#ifdef HAVE_ELEMENTARY_WL2
if (sd->wl.win)
{
Ecore_Wl2_Display *ewd = ecore_wl2_window_display_get(sd->wl.win);
if (ewd->wl.teamwork)
zwp_teamwork_deactivate_uri(ewd->wl.teamwork, ecore_wl2_window_surface_get(sd->wl.win), sd->teamwork_uri);
}
#endif
eina_stringshare_replace(&sd->teamwork_uri, NULL);
}
static EOLIAN void
_elm_win_teamwork_uri_open(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *uri)
{
EINA_SAFETY_ON_NULL_RETURN(uri);
#ifdef HAVE_ELEMENTARY_X
if (sd->x.xwin)
{
ecore_x_window_prop_string_set(sd->x.xwin, ECORE_X_ATOM_TEAMWORK_PROPERTY, uri);
ecore_x_client_message32_send(sd->x.xwin, ECORE_X_ATOM_TEAMWORK_OPEN,
ECORE_X_EVENT_MASK_WINDOW_MANAGE | ECORE_X_EVENT_MASK_WINDOW_CHILD_CONFIGURE, EFL_TEAMWORK_VERSION, 0, 0, 0, 0);
}
#endif
#ifdef HAVE_ELEMENTARY_WL2
if (sd->wl.win)
{
Ecore_Wl2_Display *ewd = ecore_wl2_window_display_get(sd->wl.win);
if (ewd->wl.teamwork)
zwp_teamwork_open_uri(ewd->wl.teamwork, ecore_wl2_window_surface_get(sd->wl.win), uri);
}
#endif
}
#include "elm_win.eo.c"

View File

@ -1132,6 +1132,43 @@ class Elm.Win (Elm.Widget, Elm.Interface.Atspi.Window,
@in not_modifiers: Evas.Modifier_Mask; [[This is for the keymask feature. Currently this feature is not supported.]]
}
}
teamwork_uri_preload {
[[Notify the compositor that a uri should be preloaded
@since 1.18
]]
params {
@in uri: const(char)*; [[This is the uri to notify with]]
}
}
teamwork_uri_show {
[[Notify the compositor that a uri should be displayed
Sends the current mouse coordinates as a hint for displaying the
related uri in the compositor.
@since 1.18
]]
params {
@in uri: const(char)*; [[This is the uri to notify with]]
}
}
teamwork_uri_hide {
[[Notify the compositor that a uri should be hidden
Hides any uri-related media displayed in the compositor through
previous \@ref elm_win_teamwork_uri_show request
@since 1.18
]]
}
teamwork_uri_open {
[[Notify the compositor that a uri should be opened
Use the compositor's default application to open a uri
@since 1.18
]]
params {
@in uri: const(char)*; [[This is the uri to open]]
}
}
}
implements {
class.constructor;

View File

@ -20,10 +20,10 @@
#include <Ecore_Input.h>
#include <Ecore_Input_Evas.h>
#include <Ecore_Wl2.h>
#include "ecore_wl2_private.h"
#include <Ecore_Evas.h>
#endif
#include "ecore_wl2_private.h"
#include "ecore_private.h"
#include "ecore_evas_private.h"
#include "ecore_evas_wayland.h"