add hooking for WL_SURFACE_ID atom on XWayland windows and composite them
in order to maximize the amount of reused code the following details the current process for xwayland compositing: * get map request from window * force reparenting * show window * await WL_SURFACE_ID x11 message * move x11 client data + pixmap onto corresponding wayland client * business as usual with wayland compositing this is pretty similar to the method of the reference code in weston, except that there's no x11 compositor in weston
This commit is contained in:
parent
c8bdacc727
commit
2b38147c43
|
@ -40,7 +40,7 @@ _e_comp_wl_focus_check(void)
|
|||
|
||||
if (stopping) return;
|
||||
ec = e_client_focused_get();
|
||||
if ((!ec) || (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL))
|
||||
if ((!ec) || e_pixmap_is_x(ec->pixmap))
|
||||
e_grabinput_focus(e_comp->ee_win, E_FOCUS_METHOD_PASSIVE);
|
||||
}
|
||||
|
||||
|
@ -1442,7 +1442,8 @@ static void
|
|||
_e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct wl_resource *resource, uint32_t id)
|
||||
{
|
||||
struct wl_resource *res;
|
||||
E_Client *ec = NULL;
|
||||
E_Client *wc, *ec = NULL;
|
||||
Eina_List *l;
|
||||
pid_t pid;
|
||||
|
||||
DBG("Compositor Cb Surface Create: %d", id);
|
||||
|
@ -1491,7 +1492,15 @@ _e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct wl_reso
|
|||
|
||||
/* set reference to pixmap so we can fetch it later */
|
||||
wl_resource_set_user_data(res, ec);
|
||||
|
||||
#ifndef HAVE_WAYLAND_ONLY
|
||||
EINA_LIST_FOREACH(e_comp->wl_comp_data->xwl_pending, l, wc)
|
||||
{
|
||||
if (!e_pixmap_is_x(wc->pixmap)) continue;
|
||||
if (wl_resource_get_id(res) != ((E_Comp_X_Client_Data*)ec->comp_data)->surface_id) continue;
|
||||
e_comp_x_xwayland_client_setup(wc, ec);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* emit surface create signal */
|
||||
wl_signal_emit(&e_comp->wl_comp_data->signals.surface.create, res);
|
||||
}
|
||||
|
@ -2964,3 +2973,9 @@ e_comp_wl_output_remove(const char *id)
|
|||
/* free(output); */
|
||||
}
|
||||
}
|
||||
|
||||
EINTERN void
|
||||
e_comp_wl_xwayland_client_queue(E_Client *ec)
|
||||
{
|
||||
e_comp->wl_comp_data->xwl_pending = eina_list_append(e_comp->wl_comp_data->xwl_pending, ec);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#ifdef E_TYPEDEFS
|
||||
|
||||
# ifndef HAVE_WAYLAND_ONLY
|
||||
# include "e_comp_x.h"
|
||||
# endif
|
||||
#else
|
||||
# ifndef E_COMP_WL_H
|
||||
# define E_COMP_WL_H
|
||||
|
@ -13,6 +15,10 @@
|
|||
|
||||
# include <xkbcommon/xkbcommon.h>
|
||||
|
||||
# ifndef HAVE_WAYLAND_ONLY
|
||||
# include "e_comp_x.h"
|
||||
# endif
|
||||
|
||||
/* # ifdef HAVE_WAYLAND_EGL */
|
||||
/* # include <EGL/egl.h> */
|
||||
/* # define GL_GLEXT_PROTOTYPES */
|
||||
|
@ -211,6 +217,7 @@ struct _E_Comp_Wl_Data
|
|||
Ecore_Idler *idler;
|
||||
|
||||
struct wl_client *xwl_client;
|
||||
Eina_List *xwl_pending;
|
||||
|
||||
/* Eina_List *retry_clients; */
|
||||
/* Ecore_Timer *retry_timer; */
|
||||
|
@ -254,6 +261,10 @@ struct _E_Comp_Wl_Client_Data
|
|||
{
|
||||
int32_t x, y;
|
||||
} popup;
|
||||
#ifndef HAVE_WAYLAND_ONLY
|
||||
E_Pixmap *xwayland_pixmap;
|
||||
E_Comp_X_Client_Data *xwayland_data;
|
||||
#endif
|
||||
|
||||
Eina_Bool keep_buffer : 1;
|
||||
Eina_Bool mapped : 1;
|
||||
|
@ -294,6 +305,27 @@ E_API struct wl_signal e_comp_wl_surface_create_signal_get(void);
|
|||
E_API double e_comp_wl_idle_time_get(void);
|
||||
E_API Eina_Bool e_comp_wl_output_init(const char *id, const char *make, const char *model, int x, int y, int w, int h, int pw, int ph, unsigned int refresh, unsigned int subpixel, unsigned int transform);
|
||||
E_API void e_comp_wl_output_remove(const char *id);
|
||||
# ifndef HAVE_WAYLAND_ONLY
|
||||
EINTERN void e_comp_wl_xwayland_client_queue(E_Client *ec);
|
||||
static inline E_Comp_X_Client_Data *
|
||||
e_comp_wl_client_xwayland_data(const E_Client *ec)
|
||||
{
|
||||
return ec->comp_data ? ((E_Comp_Wl_Client_Data*)ec->comp_data)->xwayland_data : NULL;
|
||||
}
|
||||
|
||||
static inline E_Pixmap *
|
||||
e_comp_wl_client_xwayland_pixmap(const E_Client *ec)
|
||||
{
|
||||
return ((E_Comp_Wl_Client_Data*)ec->comp_data)->xwayland_pixmap;
|
||||
}
|
||||
|
||||
static inline void
|
||||
e_comp_wl_client_xwayland_setup(E_Client *ec, E_Comp_X_Client_Data *cd, E_Pixmap *ep)
|
||||
{
|
||||
((E_Comp_Wl_Client_Data*)ec->comp_data)->xwayland_data = cd;
|
||||
((E_Comp_Wl_Client_Data*)ec->comp_data)->xwayland_pixmap = ep;
|
||||
e_comp->wl_comp_data->xwl_pending = eina_list_remove(e_comp->wl_comp_data->xwl_pending, ec);
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
|
|
@ -57,6 +57,8 @@ static Eina_Bool screensaver_dimmed = EINA_FALSE;
|
|||
static Ecore_X_Atom backlight_atom = 0;
|
||||
extern double e_bl_val;
|
||||
|
||||
static void _e_comp_x_hook_client_pre_frame_assign(void *d EINA_UNUSED, E_Client *ec);
|
||||
|
||||
static Eina_Bool
|
||||
_e_comp_x_flusher(void *data EINA_UNUSED)
|
||||
{
|
||||
|
@ -1142,6 +1144,15 @@ _e_comp_x_show_request(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Eve
|
|||
ecore_x_window_show(ev->win);
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
if ((e_comp->comp_type != E_PIXMAP_TYPE_X) && ec->ignored)
|
||||
{
|
||||
ec->visible = 1;
|
||||
if (ec->comp_data->need_reparent)
|
||||
_e_comp_x_hook_client_pre_frame_assign(NULL, ec);
|
||||
else
|
||||
ecore_x_window_show(ev->win);
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
if ((!ec->comp_data->reparented) && (!e_client_util_ignored_get(ec)))
|
||||
{
|
||||
|
@ -1395,7 +1406,7 @@ _e_comp_x_configure(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Event_
|
|||
EINA_RECTANGLE_SET(&ec->client, ev->x, ev->y, ev->w, ev->h);
|
||||
if (move)
|
||||
evas_object_move(ec->frame, ev->x, ev->y);
|
||||
if (resize)
|
||||
if (resize && e_pixmap_is_x(ec->pixmap))
|
||||
{
|
||||
e_pixmap_dirty(ec->pixmap);
|
||||
evas_object_resize(ec->frame, ev->w, ev->h);
|
||||
|
@ -1993,6 +2004,25 @@ _e_comp_x_message(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Event_Cl
|
|||
break;
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_WAYLAND
|
||||
else if (ev->message_type == WL_SURFACE_ID)
|
||||
{
|
||||
void *res;
|
||||
E_Client *wc = NULL;
|
||||
|
||||
if (e_comp->comp_type != E_PIXMAP_TYPE_WL) return ECORE_CALLBACK_RENEW;
|
||||
res = wl_client_get_object(e_comp->wl_comp_data->xwl_client, ev->data.l[0]);
|
||||
if (res)
|
||||
wc = wl_resource_get_user_data(res);
|
||||
if (wc)
|
||||
e_comp_x_xwayland_client_setup(ec, wc);
|
||||
else
|
||||
{
|
||||
ec->comp_data->surface_id = ev->data.l[0];
|
||||
e_comp_wl_xwayland_client_queue(ec);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
|
@ -2737,7 +2767,10 @@ _e_comp_x_hook_client_pre_frame_assign(void *d EINA_UNUSED, E_Client *ec)
|
|||
ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
|
||||
0, 0, 0, 0, 0,
|
||||
win, ECORE_X_WINDOW_STACK_ABOVE);
|
||||
ecore_x_event_mask_set(pwin, ECORE_X_EVENT_MASK_MOUSE_IN | ECORE_X_EVENT_MASK_MOUSE_OUT);
|
||||
ecore_x_event_mask_set(pwin, ECORE_X_EVENT_MASK_KEY_DOWN | ECORE_X_EVENT_MASK_KEY_UP |
|
||||
ECORE_X_EVENT_MASK_MOUSE_MOVE | ECORE_X_EVENT_MASK_MOUSE_DOWN |
|
||||
ECORE_X_EVENT_MASK_MOUSE_UP | ECORE_X_EVENT_MASK_MOUSE_WHEEL |
|
||||
ECORE_X_EVENT_MASK_MOUSE_IN | ECORE_X_EVENT_MASK_MOUSE_OUT);
|
||||
ecore_x_window_border_width_set(win, 0);
|
||||
ec->border_size = 0;
|
||||
|
||||
|
@ -4090,6 +4123,7 @@ _e_comp_x_hook_client_new(void *d EINA_UNUSED, E_Client *ec)
|
|||
ec->icccm.state = ECORE_X_WINDOW_STATE_HINT_NONE;
|
||||
|
||||
if (!_e_comp_x_client_new_helper(ec)) return;
|
||||
ec->ignored |= e_comp->comp_type == E_PIXMAP_TYPE_WL;
|
||||
|
||||
ec->comp_data->first_damage = ec->internal;
|
||||
|
||||
|
@ -4561,16 +4595,19 @@ _e_comp_x_randr_change(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev
|
|||
if ((e_comp->w != e_randr2->w) ||
|
||||
(e_comp->h != e_randr2->h))
|
||||
{
|
||||
e_comp_canvas_resize(e_randr2->w, e_randr2->h);
|
||||
if (e_comp->comp_type == E_PIXMAP_TYPE_X)
|
||||
e_comp_canvas_resize(e_randr2->w, e_randr2->h);
|
||||
}
|
||||
else
|
||||
{
|
||||
E_Client *ec;
|
||||
|
||||
ecore_x_netwm_desk_size_set(e_comp->root, e_comp->w, e_comp->h);
|
||||
e_randr2_screens_setup(e_comp->w, e_comp->h);
|
||||
if (e_comp->comp_type == E_PIXMAP_TYPE_X)
|
||||
e_randr2_screens_setup(e_comp->w, e_comp->h);
|
||||
|
||||
e_comp_canvas_update();
|
||||
if (e_comp->comp_type == E_PIXMAP_TYPE_X)
|
||||
e_comp_canvas_update();
|
||||
E_CLIENT_FOREACH(ec)
|
||||
{
|
||||
if (!e_client_util_ignored_get(ec))
|
||||
|
@ -4891,6 +4928,7 @@ _e_comp_x_setup(Ecore_X_Window root, int w, int h)
|
|||
e_hints_init(root, e_comp->cm_selection);
|
||||
ecore_x_window_background_color_set(root, 0, 0, 0);
|
||||
ecore_x_screen_is_composited_set(0, e_comp->cm_selection);
|
||||
ecore_x_selection_owner_set(e_comp->cm_selection, ecore_x_atom_get("WM_S0"), ecore_x_current_time_get());
|
||||
|
||||
e_comp->win = ecore_x_composite_render_window_enable(root);
|
||||
if (!e_comp->win)
|
||||
|
@ -4937,7 +4975,10 @@ _e_comp_x_setup(Ecore_X_Window root, int w, int h)
|
|||
e_comp->bindings_grab_cb = _e_comp_x_bindings_grab_cb;
|
||||
e_comp->bindings_ungrab_cb = _e_comp_x_bindings_ungrab_cb;
|
||||
|
||||
if (!e_comp_canvas_init(w, h)) return EINA_FALSE;
|
||||
if (e_comp->comp_type == E_PIXMAP_TYPE_NONE)
|
||||
{
|
||||
if (!e_comp_canvas_init(w, h)) return EINA_FALSE;
|
||||
}
|
||||
|
||||
e_grabinput_focus(e_comp->ee_win, E_FOCUS_METHOD_PASSIVE);
|
||||
|
||||
|
@ -4959,6 +5000,7 @@ _e_comp_x_setup(Ecore_X_Window root, int w, int h)
|
|||
ec->lock_client_stacking = 1;
|
||||
ec->internal = 1;
|
||||
ec->visible = 1;
|
||||
evas_object_del(e_comp->layers[i].obj);
|
||||
e_comp->layers[i].obj = ec->frame;
|
||||
evas_object_layer_set(ec->frame, e_comp_canvas_layer_map_to(i));
|
||||
evas_object_pass_events_set(ec->frame, 1);
|
||||
|
@ -4968,11 +5010,14 @@ _e_comp_x_setup(Ecore_X_Window root, int w, int h)
|
|||
ecore_x_window_lower(e_comp->layers[i].win);
|
||||
|
||||
ecore_evas_lower(e_comp->ee);
|
||||
e_comp->pointer = e_pointer_window_new(e_comp->root, 0);
|
||||
e_comp->pointer->color = ecore_x_cursor_color_supported_get();
|
||||
e_pointer_type_push(e_comp->pointer, e_comp->pointer, "default");
|
||||
if (e_comp->comp_type == E_PIXMAP_TYPE_NONE)
|
||||
{
|
||||
e_comp->pointer = e_pointer_window_new(e_comp->root, 0);
|
||||
e_comp->pointer->color = ecore_x_cursor_color_supported_get();
|
||||
e_pointer_type_push(e_comp->pointer, e_comp->pointer, "default");
|
||||
ecore_x_icccm_state_set(ecore_evas_window_get(e_comp->ee), ECORE_X_WINDOW_STATE_HINT_NORMAL);
|
||||
}
|
||||
_e_comp_x_manage_windows();
|
||||
ecore_x_icccm_state_set(ecore_evas_window_get(e_comp->ee), ECORE_X_WINDOW_STATE_HINT_NORMAL);
|
||||
|
||||
{
|
||||
E_Client *ec;
|
||||
|
@ -4994,8 +5039,11 @@ _e_comp_x_screens_setup(void)
|
|||
Ecore_X_Window root;
|
||||
int rw, rh;
|
||||
|
||||
e_comp_x_randr_screen_iface_set();
|
||||
if (!e_randr2_init()) return 0;
|
||||
if (e_comp->comp_type == E_PIXMAP_TYPE_NONE)
|
||||
{
|
||||
e_comp_x_randr_screen_iface_set();
|
||||
if (!e_randr2_init()) return 0;
|
||||
}
|
||||
root = ecore_x_window_root_first_get();
|
||||
if (!root)
|
||||
{
|
||||
|
@ -5003,11 +5051,12 @@ _e_comp_x_screens_setup(void)
|
|||
return 0;
|
||||
}
|
||||
ecore_x_window_size_get(root, &rw, &rh);
|
||||
e_randr2_screens_setup(rw, rh);
|
||||
if (e_comp->comp_type == E_PIXMAP_TYPE_NONE)
|
||||
e_randr2_screens_setup(rw, rh);
|
||||
return _e_comp_x_setup(root, rw, rh);
|
||||
}
|
||||
|
||||
EINTERN Eina_Bool
|
||||
E_API Eina_Bool
|
||||
e_comp_x_init(void)
|
||||
{
|
||||
if (!ecore_x_init(NULL))
|
||||
|
@ -5143,7 +5192,7 @@ e_comp_x_init(void)
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EINTERN void
|
||||
E_API void
|
||||
e_comp_x_shutdown(void)
|
||||
{
|
||||
E_FREE_LIST(handlers, ecore_event_handler_del);
|
||||
|
@ -5170,3 +5219,43 @@ e_comp_x_nocomp_end(void)
|
|||
ecore_x_composite_redirect_subwindows(e_comp->root, ECORE_X_COMPOSITE_UPDATE_MANUAL);
|
||||
_e_comp_x_focus_check();
|
||||
}
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
EINTERN void
|
||||
e_comp_x_xwayland_client_setup(E_Client *ec, E_Client *wc)
|
||||
{
|
||||
Ecore_X_Window win;
|
||||
E_Comp_X_Client_Data *cd;
|
||||
|
||||
win = e_client_util_win_get(ec);
|
||||
cd = ec->comp_data;
|
||||
e_comp_wl_client_xwayland_setup(wc, cd, e_pixmap_ref(ec->pixmap));
|
||||
eina_hash_del(damages_hash, &cd->damage, ec);
|
||||
ecore_x_damage_free(cd->damage);
|
||||
E_FREE_FUNC(cd->first_draw_delay, ecore_timer_del);
|
||||
cd->damage = 0;
|
||||
ec->comp_data = NULL;
|
||||
cd->evas_init = 0;
|
||||
_e_comp_x_client_evas_init(wc);
|
||||
wc->borderless = ec->borderless;
|
||||
wc->border.changed = 1;
|
||||
EC_CHANGED(wc);
|
||||
wc->depth = ec->depth;
|
||||
wc->override = ec->override;
|
||||
wc->placed = ec->placed;
|
||||
wc->input_only = ec->input_only;
|
||||
wc->border_size = ec->border_size;
|
||||
memcpy(&wc->icccm, &ec->icccm, sizeof(ec->icccm));
|
||||
memcpy(&wc->netwm, &ec->netwm, sizeof(ec->netwm));
|
||||
memcpy(&wc->e, &ec->e, sizeof(ec->e));
|
||||
ec->new_client = 1;
|
||||
e_comp->new_clients++;
|
||||
|
||||
eina_hash_set(clients_win_hash, &win, wc);
|
||||
wc->visible = 1;
|
||||
evas_object_show(wc->frame);
|
||||
e_object_del(E_OBJECT(ec));
|
||||
e_hints_window_visible_set(wc);
|
||||
_e_comp_x_client_stack(wc);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -87,6 +87,9 @@ struct _E_Comp_X_Client_Data
|
|||
Ecore_X_Illume_Window_State state;
|
||||
} win_state;
|
||||
} illume;
|
||||
#ifdef HAVE_WAYLAND
|
||||
uint32_t surface_id;
|
||||
#endif
|
||||
|
||||
Eina_Bool moving : 1;
|
||||
Eina_Bool first_map : 1;
|
||||
|
@ -102,10 +105,11 @@ struct _E_Comp_X_Client_Data
|
|||
Eina_Bool unredirected_single : 1;
|
||||
};
|
||||
|
||||
EINTERN Eina_Bool e_comp_x_init(void);
|
||||
EINTERN void e_comp_x_shutdown(void);
|
||||
E_API Eina_Bool e_comp_x_init(void);
|
||||
E_API void e_comp_x_shutdown(void);
|
||||
|
||||
E_API void e_alert_composite_win(Ecore_X_Window root, Ecore_X_Window win);
|
||||
EINTERN void e_comp_x_nocomp_end(void);
|
||||
EINTERN void e_comp_x_xwayland_client_setup(E_Client *ec, E_Client *wc);
|
||||
# endif
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue