Shell work for elm apps

Signed-off-by: Chris Michael <devilhorns@comcast.net>
This commit is contained in:
Chris Michael 2013-06-18 21:08:50 +01:00
parent d6b51b7b4c
commit cc6e76384c
2 changed files with 162 additions and 8 deletions

View File

@ -5,11 +5,15 @@
static void _e_desktop_shell_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED); static void _e_desktop_shell_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED);
static void _e_desktop_shell_cb_bind(struct wl_client *client, void *data, unsigned int version EINA_UNUSED, unsigned int id); static void _e_desktop_shell_cb_bind(struct wl_client *client, void *data, unsigned int version EINA_UNUSED, unsigned int id);
static void _e_desktop_shell_cb_shell_surface_get(struct wl_client *client, struct wl_resource *resource, unsigned int id, struct wl_resource *surface_resource); static void _e_desktop_shell_cb_shell_surface_get(struct wl_client *client, struct wl_resource *resource, unsigned int id, struct wl_resource *surface_resource);
static void _e_desktop_shell_cb_ping(E_Surface *es, unsigned int serial);
static int _e_desktop_shell_cb_ping_timeout(void *data);
static void _e_desktop_shell_shell_surface_cb_destroy_notify(struct wl_listener *listener, void *data EINA_UNUSED); static void _e_desktop_shell_shell_surface_cb_destroy_notify(struct wl_listener *listener, void *data EINA_UNUSED);
static void _e_desktop_shell_shell_surface_cb_destroy(struct wl_resource *resource); static void _e_desktop_shell_shell_surface_cb_destroy(struct wl_resource *resource);
static void _e_desktop_shell_shell_surface_configure(E_Surface *es, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h); static void _e_desktop_shell_shell_surface_configure(E_Surface *es, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
static void _e_desktop_shell_shell_surface_activate(E_Surface *es, E_Input *seat);
static void _e_desktop_shell_shell_surface_map(E_Surface *es, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h); static void _e_desktop_shell_shell_surface_map(E_Surface *es, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
static void _e_desktop_shell_shell_surface_unmap(E_Surface *es); static void _e_desktop_shell_shell_surface_unmap(E_Surface *es);
static Eina_Bool _e_desktop_shell_shell_surface_move(E_Shell_Surface *ess, E_Input *seat);
/* shell surface interface prototypes */ /* shell surface interface prototypes */
static void _e_desktop_shell_shell_surface_cb_pong(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, unsigned int serial); static void _e_desktop_shell_shell_surface_cb_pong(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, unsigned int serial);
@ -27,13 +31,16 @@ static void _e_desktop_shell_shell_surface_type_reset(E_Shell_Surface *ess);
static void _e_desktop_shell_surface_map_toplevel(E_Shell_Surface *ess); static void _e_desktop_shell_surface_map_toplevel(E_Shell_Surface *ess);
static void _e_desktop_shell_surface_map_popup(E_Shell_Surface *ess); static void _e_desktop_shell_surface_map_popup(E_Shell_Surface *ess);
static void _e_desktop_shell_popup_grab_add(E_Shell_Surface *ess, E_Input *seat);
static void _e_desktop_shell_popup_grab_add(E_Shell_Surface *ess, E_Input *seat);
static void _e_desktop_shell_popup_grab_focus(E_Input_Pointer_Grab *grab); static void _e_desktop_shell_popup_grab_focus(E_Input_Pointer_Grab *grab);
static void _e_desktop_shell_popup_grab_motion(E_Input_Pointer_Grab *grab, unsigned int timestamp); static void _e_desktop_shell_popup_grab_motion(E_Input_Pointer_Grab *grab, unsigned int timestamp);
static void _e_desktop_shell_popup_grab_button(E_Input_Pointer_Grab *grab, unsigned int timestamp, unsigned int button, unsigned int state); static void _e_desktop_shell_popup_grab_button(E_Input_Pointer_Grab *grab, unsigned int timestamp, unsigned int button, unsigned int state);
static void _e_desktop_shell_popup_grab_end(E_Input_Pointer *pointer); static void _e_desktop_shell_popup_grab_end(E_Input_Pointer *pointer);
static void _e_desktop_shell_pointer_focus_listener_add(E_Input *seat);
static void _e_desktop_shell_pointer_cb_focus(struct wl_listener *listener, void *data);
/* local wayland interfaces */ /* local wayland interfaces */
static const struct wl_shell_interface _e_desktop_shell_interface = static const struct wl_shell_interface _e_desktop_shell_interface =
{ {
@ -69,6 +76,8 @@ e_modapi_init(E_Module *m)
{ {
E_Desktop_Shell *shell; E_Desktop_Shell *shell;
struct wl_global *global; struct wl_global *global;
Eina_List *l;
E_Input *seat;
/* try to allocate space for our shell */ /* try to allocate space for our shell */
if (!(shell = E_NEW(E_Desktop_Shell, 1))) if (!(shell = E_NEW(E_Desktop_Shell, 1)))
@ -84,6 +93,8 @@ e_modapi_init(E_Module *m)
/* set a reference to this shell in the compositor */ /* set a reference to this shell in the compositor */
shell->compositor->shell_interface.shell = shell; shell->compositor->shell_interface.shell = shell;
shell->compositor->cb_ping = _e_desktop_shell_cb_ping;
/* try to add this shell to the globals */ /* try to add this shell to the globals */
if (!(global = if (!(global =
wl_display_add_global(_e_comp->wl.display, &wl_shell_interface, wl_display_add_global(_e_comp->wl.display, &wl_shell_interface,
@ -95,6 +106,9 @@ e_modapi_init(E_Module *m)
/* TODO: finish me */ /* TODO: finish me */
EINA_LIST_FOREACH(_e_comp->inputs, l, seat)
_e_desktop_shell_pointer_focus_listener_add(seat);
return m; return m;
err: err:
@ -181,8 +195,7 @@ _e_desktop_shell_cb_shell_surface_get(struct wl_client *client, struct wl_resour
/* setup shell surface destroy callback */ /* setup shell surface destroy callback */
ess->wl.surface_destroy.notify = ess->wl.surface_destroy.notify =
_e_desktop_shell_shell_surface_cb_destroy_notify; _e_desktop_shell_shell_surface_cb_destroy_notify;
wl_signal_add(&es->wl.resource.destroy_signal, wl_signal_add(&es->signals.destroy, &ess->wl.surface_destroy);
&ess->wl.surface_destroy);
/* setup shell surface interface */ /* setup shell surface interface */
ess->wl.resource.destroy = _e_desktop_shell_shell_surface_cb_destroy; ess->wl.resource.destroy = _e_desktop_shell_shell_surface_cb_destroy;
@ -193,6 +206,52 @@ _e_desktop_shell_cb_shell_surface_get(struct wl_client *client, struct wl_resour
wl_client_add_resource(client, &ess->wl.resource); wl_client_add_resource(client, &ess->wl.resource);
} }
static void
_e_desktop_shell_cb_ping(E_Surface *es, unsigned int serial)
{
E_Shell_Surface *ess;
if (!(ess = es->shell_surface)) return;
if (!ess->wl.resource.client) return;
/* FIXME */
if (!ess->ping_timer)
{
struct wl_event_loop *loop;
if (!(ess->ping_timer = E_NEW(E_Shell_Surface_Ping_Timer, 1)))
return;
ess->ping_timer->serial = serial;
loop = wl_display_get_event_loop(_e_comp->wl.display);
ess->ping_timer->source =
wl_event_loop_add_timer(loop, _e_desktop_shell_cb_ping_timeout, ess);
wl_event_source_timer_update(ess->ping_timer->source, 200);
wl_shell_surface_send_ping(&ess->wl.resource, serial);
}
}
static int
_e_desktop_shell_cb_ping_timeout(void *data)
{
E_Shell_Surface *ess;
E_Input *seat;
Eina_List *l;
if (!(ess = data)) return 0;
ess->active = EINA_FALSE;
EINA_LIST_FOREACH(_e_comp->inputs, l, seat)
{
if (seat->pointer->focus == ess->surface)
{
printf("Set Busy Cursor\n");
}
}
return 1;
}
static void static void
_e_desktop_shell_shell_surface_cb_destroy_notify(struct wl_listener *listener, void *data EINA_UNUSED) _e_desktop_shell_shell_surface_cb_destroy_notify(struct wl_listener *listener, void *data EINA_UNUSED)
{ {
@ -282,9 +341,18 @@ _e_desktop_shell_shell_surface_configure(E_Surface *es, Evas_Coord x, Evas_Coord
} }
} }
static void
_e_desktop_shell_shell_surface_activate(E_Surface *es, E_Input *seat)
{
e_surface_activate(es, seat);
}
static void static void
_e_desktop_shell_shell_surface_map(E_Surface *es, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) _e_desktop_shell_shell_surface_map(E_Surface *es, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
{ {
Eina_List *l;
E_Input *seat;
/* safety check */ /* safety check */
if (!es) return; if (!es) return;
@ -323,7 +391,7 @@ _e_desktop_shell_shell_surface_map(E_Surface *es, Evas_Coord x, Evas_Coord y, Ev
if (es->shell_surface->type != E_SHELL_SURFACE_TYPE_NONE) if (es->shell_surface->type != E_SHELL_SURFACE_TYPE_NONE)
e_surface_output_assign(es); e_surface_output_assign(es);
/* activate */ /* map */
switch (es->shell_surface->type) switch (es->shell_surface->type)
{ {
case E_SHELL_SURFACE_TYPE_TOPLEVEL: case E_SHELL_SURFACE_TYPE_TOPLEVEL:
@ -335,6 +403,21 @@ _e_desktop_shell_shell_surface_map(E_Surface *es, Evas_Coord x, Evas_Coord y, Ev
default: default:
break; break;
} }
/* activate */
switch (es->shell_surface->type)
{
case E_SHELL_SURFACE_TYPE_TOPLEVEL:
case E_SHELL_SURFACE_TYPE_FULLSCREEN:
case E_SHELL_SURFACE_TYPE_MAXIMIZED:
EINA_LIST_FOREACH(_e_comp->inputs, l, seat)
_e_desktop_shell_shell_surface_activate(es, seat);
break;
default:
break;
}
es->mapped = EINA_TRUE;
} }
static void static void
@ -360,6 +443,12 @@ _e_desktop_shell_shell_surface_unmap(E_Surface *es)
es->mapped = EINA_FALSE; es->mapped = EINA_FALSE;
} }
static Eina_Bool
_e_desktop_shell_shell_surface_move(E_Shell_Surface *ess, E_Input *seat)
{
return EINA_FALSE;
}
/* shell surface interface functions */ /* shell surface interface functions */
static void static void
_e_desktop_shell_shell_surface_cb_pong(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, unsigned int serial) _e_desktop_shell_shell_surface_cb_pong(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, unsigned int serial)
@ -368,17 +457,39 @@ _e_desktop_shell_shell_surface_cb_pong(struct wl_client *client EINA_UNUSED, str
/* try to cast the resource to our shell surface */ /* try to cast the resource to our shell surface */
if (!(ess = resource->data)) return; if (!(ess = resource->data)) return;
printf("Shell Surface Pong\n"); if (!ess->ping_timer) return;
if (ess->ping_timer->serial == serial)
{
ess->active = EINA_TRUE;
/* TODO: Unset busy cursor */
if (ess->ping_timer->source)
wl_event_source_remove(ess->ping_timer->source);
E_FREE(ess->ping_timer);
}
} }
static void static void
_e_desktop_shell_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource, unsigned int serial) _e_desktop_shell_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource, unsigned int serial)
{ {
E_Shell_Surface *ess; E_Shell_Surface *ess;
E_Input *seat;
/* try to cast the resource to our shell surface */ /* try to cast the resource to our shell surface */
if (!(ess = resource->data)) return; if (!(ess = resource->data)) return;
if (!(seat = seat_resource->data)) return;
printf("Shell Surface Move\n"); printf("Shell Surface Move\n");
if ((seat->pointer->grab->button_count == 0) ||
(seat->pointer->grab->serial != serial))
return;
if (!_e_desktop_shell_shell_surface_move(ess, seat))
wl_resource_post_no_memory(resource);
} }
static void static void
@ -447,7 +558,8 @@ _e_desktop_shell_shell_surface_cb_popup_set(struct wl_client *client EINA_UNUSED
ess->ntype = E_SHELL_SURFACE_TYPE_POPUP; ess->ntype = E_SHELL_SURFACE_TYPE_POPUP;
ess->parent = parent_resource->data; ess->parent = parent_resource->data;
ess->popup.seat = seat_resource->data; ess->popup.seat = seat_resource->data;
ess->popup.serial = serial; /* FIXME: BIG GIAN HACK !!! */
ess->popup.serial = serial - 1;
ess->popup.x = x; ess->popup.x = x;
ess->popup.y = y; ess->popup.y = y;
} }
@ -610,6 +722,9 @@ _e_desktop_shell_surface_map_popup(E_Shell_Surface *ess)
es->geometry.y = ess->popup.y; es->geometry.y = ess->popup.y;
es->geometry.changed = EINA_TRUE; es->geometry.changed = EINA_TRUE;
printf("Popup Serial: %d\n", ess->popup.serial);
printf("Grab Serial: %d\n", seat->pointer->grab->serial);
if ((seat) && (seat->pointer->grab->serial == ess->popup.serial)) if ((seat) && (seat->pointer->grab->serial == ess->popup.serial))
_e_desktop_shell_popup_grab_add(ess, seat); _e_desktop_shell_popup_grab_add(ess, seat);
else else
@ -641,13 +756,12 @@ _e_desktop_shell_popup_grab_focus(E_Input_Pointer_Grab *grab)
{ {
E_Input_Pointer *ptr; E_Input_Pointer *ptr;
E_Surface *es; E_Surface *es;
struct wl_client *client;
if (!(ptr = grab->pointer)) return; if (!(ptr = grab->pointer)) return;
es = e_compositor_surface_find(ptr->seat->compositor, ptr->x, ptr->y); es = e_compositor_surface_find(ptr->seat->compositor, ptr->x, ptr->y);
if ((es) && (es->wl.resource.client == grab->client)) if ((es) && (wl_resource_get_client(es->wl.resource) == grab->client))
e_input_pointer_focus_set(ptr, es, ptr->x, ptr->y); e_input_pointer_focus_set(ptr, es, ptr->x, ptr->y);
else else
e_input_pointer_focus_set(ptr, NULL, 0, 0); e_input_pointer_focus_set(ptr, NULL, 0, 0);
@ -675,6 +789,7 @@ _e_desktop_shell_popup_grab_button(E_Input_Pointer_Grab *grab, unsigned int time
disp = wl_client_get_display(res->client); disp = wl_client_get_display(res->client);
serial = wl_display_get_serial(disp); serial = wl_display_get_serial(disp);
wl_pointer_send_button(res, serial, timestamp, button, state); wl_pointer_send_button(res, serial, timestamp, button, state);
} }
else if ((state == WL_POINTER_BUTTON_STATE_RELEASED) && else if ((state == WL_POINTER_BUTTON_STATE_RELEASED) &&
@ -706,3 +821,41 @@ _e_desktop_shell_popup_grab_end(E_Input_Pointer *pointer)
wl_list_init(&grab->surfaces); wl_list_init(&grab->surfaces);
} }
} }
static void
_e_desktop_shell_pointer_focus_listener_add(E_Input *seat)
{
struct wl_listener *listener;
if (!seat->pointer) return;
listener = malloc(sizeof(*listener));
listener->notify = _e_desktop_shell_pointer_cb_focus;
wl_signal_add(&seat->pointer->signals.focus, listener);
}
static void
_e_desktop_shell_pointer_cb_focus(struct wl_listener *listener, void *data)
{
E_Input_Pointer *ptr;
E_Surface *es;
E_Shell_Surface *ess;
E_Compositor *comp;
if (!(ptr = data)) return;
if (!(es = ptr->focus)) return;
if (!(ess = es->shell_surface)) return;
if (!(comp = ptr->seat->compositor)) return;
if ((ess) && (!ess->active))
{
printf("\tShell Surface Not Active. Set Busy Cursor\n");
}
else
{
unsigned int serial = 0;
serial = wl_display_next_serial(comp->wl.display);
if (comp->cb_ping) comp->cb_ping(es, serial);
}
}

View File

@ -11,6 +11,7 @@ struct _E_Desktop_Shell
{ {
struct wl_resource *resource; struct wl_resource *resource;
struct wl_listener destroy_listener; struct wl_listener destroy_listener;
struct wl_listener pointer_focus_listener;
} wl; } wl;
}; };