xdg6 support

This commit is contained in:
Mike Blumenkrantz 2016-11-11 12:28:49 -05:00
parent 232c73fe83
commit 5497fadce4
8 changed files with 1553 additions and 17 deletions

View File

@ -170,7 +170,14 @@ _e_comp_cb_mouse_up(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse_Bu
{
if ((e_comp->comp_type == E_PIXMAP_TYPE_X) && (ev->event_window != e_comp->root))
return ECORE_CALLBACK_PASS_ON;
return !e_bindings_mouse_down_ecore_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(e_comp), ev);
if (e_bindings_mouse_down_ecore_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(e_comp), ev))
return ECORE_CALLBACK_DONE;
#ifdef HAVE_WAYLAND
return e_comp_wl_grab_client_mouse_button(ev);
#else
return ECORE_CALLBACK_RENEW;
#endif
}
static Eina_Bool
@ -178,7 +185,13 @@ _e_comp_cb_mouse_down(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse_
{
if ((e_comp->comp_type == E_PIXMAP_TYPE_X) && (ev->event_window != e_comp->root))
return ECORE_CALLBACK_PASS_ON;
return !e_bindings_mouse_down_ecore_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(e_comp), ev);
if (e_bindings_mouse_down_ecore_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(e_comp), ev))
return ECORE_CALLBACK_DONE;
#ifdef HAVE_WAYLAND
return e_comp_wl_grab_client_mouse_button(ev);
#else
return ECORE_CALLBACK_RENEW;
#endif
}
static Eina_Bool
@ -189,6 +202,14 @@ _e_comp_cb_mouse_wheel(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse
return !e_bindings_wheel_ecore_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(e_comp), ev);
}
#ifdef HAVE_WAYLAND
static Eina_Bool
_e_comp_cb_mouse_move(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse_Move *ev)
{
return e_comp_wl_grab_client_mouse_move(ev);
}
#endif
////////////////////////////////////
static Eina_Bool
@ -794,6 +815,9 @@ e_comp_canvas_intercept(void)
E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_comp_cb_mouse_down, NULL);
E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_BUTTON_UP, _e_comp_cb_mouse_up, NULL);
E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_WHEEL, _e_comp_cb_mouse_wheel, NULL);
#ifdef HAVE_WAYLAND
E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_MOVE, _e_comp_cb_mouse_move, NULL);
#endif
E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_KEY_DOWN, _e_comp_cb_key_down, NULL);
E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_KEY_UP, _e_comp_cb_key_up, NULL);
}

View File

@ -42,6 +42,9 @@ static double _last_event_time = 0.0;
static int64_t surface_id = 0;
static Eina_List *grab_clients;
static Eina_List *grab_cbs;
/* local functions */
static Eina_Bool
@ -116,13 +119,16 @@ _e_comp_wl_surface_outputs_update(E_Client *ec)
static void
_e_comp_wl_configure_send(E_Client *ec, Eina_Bool edges)
{
int w, h;
int w = 0, h = 0;
if (e_object_is_del(E_OBJECT(ec))) return;
if (e_comp_object_frame_exists(ec->frame))
w = ec->client.w, h = ec->client.h;
else
w = ec->w, h = ec->h;
if (e_pixmap_usable_get(ec->pixmap))
{
if (e_comp_object_frame_exists(ec->frame))
w = ec->client.w, h = ec->client.h;
else
w = ec->w, h = ec->h;
}
ec->comp_data->shell.configure_send(ec->comp_data->shell.surface,
edges * e_comp_wl->resize.edges,
w, h);
@ -1334,6 +1340,26 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
if (ec->comp_data->shell.surface)
{
if (ec->comp_data->shell.set.min_size.w)
ec->icccm.min_w = ec->comp_data->shell.set.min_size.w;
ec->comp_data->shell.set.min_size.w = 0;
if (ec->comp_data->shell.set.min_size.h)
ec->icccm.min_h = ec->comp_data->shell.set.min_size.h;
ec->comp_data->shell.set.min_size.h = 0;
if (ec->comp_data->shell.set.max_size.w)
ec->icccm.max_w = ec->comp_data->shell.set.max_size.w;
ec->comp_data->shell.set.max_size.w = 0;
if (ec->comp_data->shell.set.max_size.h)
ec->icccm.max_h = ec->comp_data->shell.set.max_size.h;
ec->comp_data->shell.set.max_size.h = 0;
if (ec->icccm.min_w && ec->icccm.max_w && (ec->icccm.min_w > ec->icccm.max_w))
wl_resource_post_error(ec->comp_data->shell.surface,
WL_DISPLAY_ERROR_INVALID_OBJECT,
"min surface width cannot be larger than max surface width");
if (ec->icccm.min_h && ec->icccm.max_h && (ec->icccm.min_h > ec->icccm.max_h))
wl_resource_post_error(ec->comp_data->shell.surface,
WL_DISPLAY_ERROR_INVALID_OBJECT,
"min surface height cannot be larger than max surface height");
if (ec->comp_data->shell.set.fullscreen && (!ec->fullscreen))
{
e_client_fullscreen(ec, E_FULLSCREEN_RESIZE);
@ -1473,6 +1499,8 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
ec->want_focus |= ec->icccm.accepts_focus && (!ec->override);
}
}
else if (first && ec->comp_data->shell.surface)
_e_comp_wl_configure_send(ec, 0);
state->sx = 0;
state->sy = 0;
@ -1839,6 +1867,11 @@ _e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct wl_reso
ec->client.w = ec->client.h = 1;
ec->comp_data->surface = res;
ec->netwm.pid = pid;
if (!ec->internal)
{
ec->icccm.min_w = ec->icccm.min_h =
ec->icccm.max_w = ec->icccm.max_h = 0;
}
if (client != e_comp_wl->xwl_client)
ec->internal = pid == getpid();
@ -3342,3 +3375,102 @@ e_comp_wl_xwayland_client_queue(E_Client *ec)
{
e_comp_wl->xwl_pending = eina_list_append(e_comp_wl->xwl_pending, ec);
}
E_API void
e_comp_wl_grab_client_add(E_Client *ec, E_Comp_Wl_Grab_End_Cb cb)
{
E_Client *gec, *parent = e_client_util_top_parent_get(ec);
E_Comp_Wl_Grab_End_Cb grabcb;
if (grab_clients && (parent != e_client_util_top_parent_get(eina_list_data_get(grab_clients))))
{
/* dismiss grabs in order when grabbing from new toplevel */
EINA_LIST_FREE(grab_clients, gec)
{
grabcb = eina_list_data_get(grab_cbs);
if (grabcb) grabcb(gec);
grab_cbs = eina_list_remove_list(grab_cbs, grab_cbs);
}
}
grab_clients = eina_list_prepend(grab_clients, ec);
grab_cbs = eina_list_prepend(grab_cbs, cb);
ec->comp_data->grab = 1;
if (eina_list_count(grab_clients) == 1) e_bindings_disabled_set(1);
}
E_API void
e_comp_wl_grab_client_del(E_Client *ec, Eina_Bool dismiss)
{
Eina_List *l, *ll;
E_Client *gec;
int n = -1;
E_Comp_Wl_Grab_End_Cb cb;
EINA_LIST_FOREACH(grab_clients, l, gec)
{
n++;
if (gec != ec) continue;
ll = eina_list_nth_list(grab_cbs, n);
cb = eina_list_data_get(ll);
if (dismiss && cb) cb(gec);
grab_cbs = eina_list_remove_list(grab_cbs, ll);
grab_clients = eina_list_remove_list(grab_clients, l);
break;
}
if (!grab_clients)
e_bindings_disabled_set(0);
}
E_API Eina_Bool
e_comp_wl_client_is_grabbed(const E_Client *ec)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
return ec->comp_data->grab && evas_object_visible_get(ec->frame);
}
static Eina_Bool
_check_grab_coords(E_Client *ec, int x, int y)
{
if (e_comp_object_coords_inside_input_area(ec->frame, x, y)) return EINA_TRUE;
while (ec->parent)
{
ec = ec->parent;
if (e_comp_object_coords_inside_input_area(ec->frame, x, y)) return EINA_TRUE;
}
return EINA_FALSE;
}
E_API Eina_Bool
e_comp_wl_grab_client_mouse_move(const Ecore_Event_Mouse_Move *ev)
{
E_Client *ec;
if (e_comp->comp_type != E_PIXMAP_TYPE_WL) return ECORE_CALLBACK_RENEW;
ec = e_client_focused_get();
if (!ec) return ECORE_CALLBACK_RENEW;
if (!e_client_util_is_popup(ec)) return ECORE_CALLBACK_RENEW;
if (!e_comp_wl_client_is_grabbed(ec)) return ECORE_CALLBACK_RENEW;
/* reject mouse moves from outside the popup */
if (_check_grab_coords(ec, ev->x, ev->y)) return ECORE_CALLBACK_RENEW;
/* manually move the pointer since we're about to block the event globally */
evas_object_move(e_comp->pointer->o_ptr, ev->x, ev->y);
return ECORE_CALLBACK_DONE;
}
E_API Eina_Bool
e_comp_wl_grab_client_mouse_button(const Ecore_Event_Mouse_Button *ev)
{
E_Client *ec;
if (e_comp->comp_type != E_PIXMAP_TYPE_WL) return ECORE_CALLBACK_RENEW;
ec = e_client_focused_get();
if (!ec) return ECORE_CALLBACK_RENEW;
if (!e_client_util_is_popup(ec)) return ECORE_CALLBACK_RENEW;
if (!e_comp_wl_client_is_grabbed(ec)) return ECORE_CALLBACK_RENEW;
/* reject mouse moves from outside the popup */
if (_check_grab_coords(ec, ev->x, ev->y)) return ECORE_CALLBACK_RENEW;
e_comp_wl_grab_client_del(ec, 1);
while (grab_clients)
e_comp_wl_grab_client_del(eina_list_last_data_get(grab_clients), 1);
return ECORE_CALLBACK_DONE;
}

View File

@ -49,6 +49,7 @@ typedef struct _E_Comp_Wl_Client_Data E_Comp_Wl_Client_Data;
typedef struct _E_Comp_Wl_Data E_Comp_Wl_Data;
typedef struct _E_Comp_Wl_Output E_Comp_Wl_Output;
typedef struct E_Shell_Data E_Shell_Data;
typedef void (*E_Comp_Wl_Grab_End_Cb)(E_Client*);
struct _E_Comp_Wl_Buffer
{
@ -287,6 +288,8 @@ struct _E_Comp_Wl_Client_Data
E_Shell_Data *data;
struct
{
Evas_Coord_Size min_size;
Evas_Coord_Size max_size;
Eina_Bool fullscreen : 1;
Eina_Bool unfullscreen : 1;
Eina_Bool maximize : 1;
@ -329,6 +332,7 @@ struct _E_Comp_Wl_Client_Data
Eina_Bool maximizing : 1;
Eina_Bool in_commit : 1;
Eina_Bool is_xdg_surface : 1;
Eina_Bool grab;
};
struct _E_Comp_Wl_Output
@ -369,6 +373,12 @@ E_API Eina_Bool e_comp_wl_evas_handle_mouse_button(E_Client *ec, uint32_t timest
E_API extern int E_EVENT_WAYLAND_GLOBAL_ADD;
E_API void e_comp_wl_grab_client_add(E_Client *ec, E_Comp_Wl_Grab_End_Cb cb);
E_API void e_comp_wl_grab_client_del(E_Client *ec, Eina_Bool dismiss);
E_API Eina_Bool e_comp_wl_client_is_grabbed(const E_Client *ec);
E_API Eina_Bool e_comp_wl_grab_client_mouse_move(const Ecore_Event_Mouse_Move *ev);
E_API Eina_Bool e_comp_wl_grab_client_mouse_button(const Ecore_Event_Mouse_Button *ev);
# ifndef HAVE_WAYLAND_ONLY
EINTERN void e_comp_wl_xwayland_client_queue(E_Client *ec);
static inline E_Comp_X_Client_Data *

View File

@ -13,6 +13,8 @@ wl_desktop_shellpkg_LTLIBRARIES = src/modules/wl_desktop_shell/module.la
wl_desktop_shell_wayland_sources = \
src/modules/wl_desktop_shell/xdg-shell-unstable-v5-protocol.c \
src/modules/wl_desktop_shell/xdg-shell-unstable-v5-server-protocol.h \
src/modules/wl_desktop_shell/xdg-shell-unstable-v6-protocol.c \
src/modules/wl_desktop_shell/xdg-shell-unstable-v6-server-protocol.h \
src/modules/wl_desktop_shell/input-method-unstable-v1-protocol.c \
src/modules/wl_desktop_shell/input-method-unstable-v1-server-protocol.h
@ -27,7 +29,8 @@ src/modules/wl_desktop_shell/e_mod_main.c \
src/modules/wl_desktop_shell/e_mod_main.h \
src/modules/wl_desktop_shell/e_mod_input_panel.c \
src/modules/wl_desktop_shell/wl_shell.c \
src/modules/wl_desktop_shell/xdg5.c
src/modules/wl_desktop_shell/xdg5.c \
src/modules/wl_desktop_shell/xdg6.c
nodist_src_modules_wl_desktop_shell_module_la_SOURCES = \
@ -38,6 +41,7 @@ MAINTAINERCLEANFILES += \
src/modules/wl_desktop_shell/e_mod_main.c: \
src/modules/wl_desktop_shell/xdg-shell-unstable-v5-server-protocol.h \
src/modules/wl_desktop_shell/xdg-shell-unstable-v6-server-protocol.h \
src/modules/wl_desktop_shell/input-method-unstable-v1-server-protocol.h
PHONIES += wl_desktop_shell install-wl_desktop_shell

View File

@ -16,15 +16,27 @@ e_shell_surface_destroy(struct wl_resource *resource)
/* get the client for this resource */
ec = wl_resource_get_user_data(resource);
if (!ec) return;
if (!e_object_unref(E_OBJECT(ec))) return;
if (e_object_is_del(E_OBJECT(ec))) return;
if (ec->comp_data->grab)
{
e_comp_wl_grab_client_del(ec, 0);
ec->comp_data->grab = 0;
}
shd = ec->comp_data->shell.data;
if (shd)
{
E_FREE_LIST(shd->pending, free);
E_FREE(ec->comp_data->shell.data);
if ((resource == ec->comp_data->shell.surface) || (resource == shd->surface))
{
if (ec->comp_data->shell.surface == resource)
ec->comp_data->shell.surface = NULL;
else
shd->surface = NULL;
E_FREE(ec->comp_data->shell.data);
}
}
if (ec->comp_data->mapped)
@ -38,8 +50,8 @@ e_shell_surface_destroy(struct wl_resource *resource)
ec->parent->transients =
eina_list_remove(ec->parent->transients, ec);
}
/* wl_resource_destroy(ec->comp_data->shell.surface); */
ec->comp_data->shell.surface = NULL;
e_object_unref(E_OBJECT(ec));
}
EINTERN void
@ -140,6 +152,8 @@ E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Wl_Desktop_Shell" };
E_API void *
e_modapi_init(E_Module *m)
{
Eina_Bool have_shell;
/* try to create global shell interface */
if (!wl_global_create(e_comp_wl->wl.disp, &wl_shell_interface, 1,
NULL, wl_shell_cb_bind))
@ -148,7 +162,9 @@ e_modapi_init(E_Module *m)
return NULL;
}
if (!e_xdg_shell_init()) return NULL;
have_shell = e_xdg_shell_v5_init();
have_shell &= e_xdg_shell_v6_init();
if (!have_shell) return NULL;
#ifdef HAVE_WL_TEXT_INPUT
if (!e_input_panel_init())

View File

@ -12,7 +12,8 @@ EINTERN void e_shell_surface_cb_destroy(struct wl_resource *resource);
EINTERN void e_shell_surface_parent_set(E_Client *ec, struct wl_resource *parent_resource);
EINTERN void e_shell_surface_mouse_down_helper(E_Client *ec, E_Binding_Event_Mouse_Button *ev, Eina_Bool move);
EINTERN Eina_Bool e_xdg_shell_init(void);
EINTERN Eina_Bool e_xdg_shell_v5_init(void);
EINTERN Eina_Bool e_xdg_shell_v6_init(void);
EINTERN void wl_shell_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id);
struct E_Shell_Data
@ -21,10 +22,11 @@ struct E_Shell_Data
int32_t width;
int32_t height;
Eina_List *pending;
struct wl_resource *surface;
void *shell;
Eina_Bool fullscreen : 1;
Eina_Bool maximized : 1;
Eina_Bool activated : 1;
};
#endif

View File

@ -860,7 +860,7 @@ _e_xdg_shell_cb_dispatch(const void *implementation EINA_UNUSED, void *target, u
return 1;
}
EINTERN void
static void
_e_xdg_shell_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
{
struct wl_resource *res;
@ -877,7 +877,7 @@ _e_xdg_shell_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t
}
EINTERN Eina_Bool
e_xdg_shell_init(void)
e_xdg_shell_v5_init(void)
{
/* try to create global xdg_shell interface */
if (!wl_global_create(e_comp_wl->wl.disp, &xdg_shell_interface, 1,

File diff suppressed because it is too large Load Diff