diff options
-rw-r--r-- | src/desktop.c | 17 | ||||
-rw-r--r-- | src/ivi-compositor.h | 30 | ||||
-rw-r--r-- | src/layout.c | 38 | ||||
-rw-r--r-- | src/main.c | 1 | ||||
-rw-r--r-- | src/shell.c | 78 |
5 files changed, 160 insertions, 4 deletions
diff --git a/src/desktop.c b/src/desktop.c index 3e36415..03a2186 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -92,7 +92,10 @@ desktop_surface_added(struct weston_desktop_surface *dsurface, void *userdata) weston_desktop_surface_set_user_data(dsurface, surface); if (ivi->shell_client.ready) { - ivi_set_desktop_surface(surface); + if (ivi_check_pending_desktop_surface_popup(surface)) + ivi_set_desktop_surface_popup(surface); + else + ivi_set_desktop_surface(surface); } else { /* * We delay creating "normal" desktop surfaces until later, to @@ -111,10 +114,13 @@ desktop_surface_removed(struct weston_desktop_surface *dsurface, void *userdata) struct weston_surface *wsurface = weston_desktop_surface_get_surface(dsurface); - struct ivi_output *output = surface->desktop.last_output; + struct ivi_output *output; - /* TODO */ - if (surface->role != IVI_SURFACE_ROLE_DESKTOP) + if (surface->role == IVI_SURFACE_ROLE_DESKTOP) + output = surface->desktop.last_output; + else if (surface->role == IVI_SURFACE_ROLE_POPUP) + output = surface->popup.output; + else return; /* reset the active surface as well */ @@ -155,6 +161,9 @@ desktop_committed(struct weston_desktop_surface *dsurface, case IVI_SURFACE_ROLE_PANEL: ivi_layout_panel_committed(surface); break; + case IVI_SURFACE_ROLE_POPUP: + ivi_layout_popup_committed(surface); + break; case IVI_SURFACE_ROLE_NONE: case IVI_SURFACE_ROLE_BACKGROUND: default: /* fall through */ diff --git a/src/ivi-compositor.h b/src/ivi-compositor.h index cd7cbdd..75c5568 100644 --- a/src/ivi-compositor.h +++ b/src/ivi-compositor.h @@ -85,11 +85,13 @@ struct ivi_compositor { struct ivi_policy *policy; struct wl_list pending_surfaces; + struct wl_list popup_pending_apps; struct weston_layer hidden; struct weston_layer background; struct weston_layer normal; struct weston_layer panel; + struct weston_layer popup; struct weston_layer fullscreen; }; @@ -136,6 +138,15 @@ enum ivi_surface_role { IVI_SURFACE_ROLE_DESKTOP, IVI_SURFACE_ROLE_BACKGROUND, IVI_SURFACE_ROLE_PANEL, + IVI_SURFACE_ROLE_POPUP, +}; + +struct pending_popup { + struct ivi_output *ioutput; + char *app_id; + int x; int y; + + struct wl_list link; /** ivi_compositor::popup_pending_surfaces */ }; struct ivi_desktop_surface { @@ -147,6 +158,12 @@ struct ivi_background_surface { struct ivi_output *output; }; +struct ivi_popup_surface { + struct ivi_output *output; + int x; + int y; +}; + struct ivi_panel_surface { struct ivi_output *output; enum agl_shell_edge edge; @@ -177,6 +194,7 @@ struct ivi_surface { struct ivi_desktop_surface desktop; struct ivi_background_surface bg; struct ivi_panel_surface panel; + struct ivi_popup_surface popup; }; }; @@ -228,6 +246,15 @@ to_ivi_output(struct weston_output *o); void ivi_set_desktop_surface(struct ivi_surface *surface); +/* + * removes the pending popup one + */ +bool +ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface); + +void +ivi_set_desktop_surface_popup(struct ivi_surface *surface); + void ivi_reflow_outputs(struct ivi_compositor *ivi); @@ -257,4 +284,7 @@ ivi_layout_desktop_committed(struct ivi_surface *surf); void ivi_layout_panel_committed(struct ivi_surface *surface); +void +ivi_layout_popup_committed(struct ivi_surface *surface); + #endif diff --git a/src/layout.c b/src/layout.c index 9537034..ff30def 100644 --- a/src/layout.c +++ b/src/layout.c @@ -282,6 +282,44 @@ skip_config_check: } void +ivi_layout_popup_committed(struct ivi_surface *surface) +{ + struct ivi_compositor *ivi = surface->ivi; + + struct weston_desktop_surface *dsurface = surface->dsurface; + struct weston_surface *wsurface = + weston_desktop_surface_get_surface(dsurface); + + struct ivi_output *output = surface->popup.output; + struct weston_output *woutput = output->output; + + struct weston_view *view = surface->view; + struct weston_geometry geom; + + if (surface->view->is_mapped) + return; + + geom = weston_desktop_surface_get_geometry(dsurface); + weston_log("geom x %d, y %d, width %d, height %d\n", geom.x, geom.y, + geom.width, geom.height); + + assert(surface->role == IVI_SURFACE_ROLE_POPUP); + + weston_view_set_output(view, woutput); + if (surface->popup.x || surface->popup.y) + weston_view_set_position(view, surface->popup.x, surface->popup.y); + else + weston_view_set_position(view, geom.x, geom.y); + weston_layer_entry_insert(&ivi->popup.view_list, &view->layer_link); + + weston_view_update_transform(view); + weston_view_schedule_repaint(view); + + wsurface->is_mapped = true; + surface->view->is_mapped = true; +} + +void ivi_layout_panel_committed(struct ivi_surface *surface) { struct ivi_compositor *ivi = surface->ivi; @@ -1147,6 +1147,7 @@ int main(int argc, char *argv[]) wl_list_init(&ivi.outputs); wl_list_init(&ivi.surfaces); wl_list_init(&ivi.pending_surfaces); + wl_list_init(&ivi.popup_pending_apps); wl_list_init(&ivi.desktop_clients); /* Prevent any clients we spawn getting our stdin */ diff --git a/src/shell.c b/src/shell.c index 0f2e644..a9be929 100644 --- a/src/shell.c +++ b/src/shell.c @@ -66,6 +66,65 @@ ivi_set_desktop_surface(struct ivi_surface *surface) } void +ivi_set_desktop_surface_popup(struct ivi_surface *surface) +{ + struct ivi_compositor *ivi = surface->ivi; + assert(surface->role == IVI_SURFACE_ROLE_NONE); + + surface->role = IVI_SURFACE_ROLE_POPUP; + wl_list_insert(&ivi->surfaces, &surface->link); +} + +static void +ivi_set_pending_desktop_surface_popup(struct ivi_output *ioutput, + int x, int y, const char *app_id) +{ + struct ivi_compositor *ivi = ioutput->ivi; + size_t len_app_id = strlen(app_id); + + struct pending_popup *p_popup = zalloc(sizeof(*p_popup)); + + p_popup->app_id = zalloc(sizeof(char) * (len_app_id + 1)); + memcpy(p_popup->app_id, app_id, len_app_id); + p_popup->ioutput = ioutput; + p_popup->x = x; + p_popup->y = y; + + wl_list_insert(&ivi->popup_pending_apps, &p_popup->link); +} + +static void +ivi_remove_pending_desktop_surface_popup(struct pending_popup *p_popup) +{ + free(p_popup->app_id); + wl_list_remove(&p_popup->link); + free(p_popup); +} + +bool +ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface) +{ + struct ivi_compositor *ivi = surface->ivi; + struct pending_popup *p_popup, *next_p_popup; + const char *_app_id = + weston_desktop_surface_get_app_id(surface->dsurface); + + wl_list_for_each_safe(p_popup, next_p_popup, + &ivi->popup_pending_apps, link) { + if (!strcmp(_app_id, p_popup->app_id)) { + surface->popup.output = p_popup->ioutput; + surface->popup.x = p_popup->x; + surface->popup.y = p_popup->y; + + ivi_remove_pending_desktop_surface_popup(p_popup); + return true; + } + } + + return false; +} + +void ivi_shell_init_black_fs(struct ivi_compositor *ivi) { struct ivi_output *out; @@ -83,6 +142,7 @@ ivi_shell_init(struct ivi_compositor *ivi) weston_layer_init(&ivi->background, ivi->compositor); weston_layer_init(&ivi->normal, ivi->compositor); weston_layer_init(&ivi->panel, ivi->compositor); + weston_layer_init(&ivi->popup, ivi->compositor); weston_layer_init(&ivi->fullscreen, ivi->compositor); weston_layer_set_position(&ivi->hidden, @@ -93,6 +153,8 @@ ivi_shell_init(struct ivi_compositor *ivi) WESTON_LAYER_POSITION_NORMAL); weston_layer_set_position(&ivi->panel, WESTON_LAYER_POSITION_UI); + weston_layer_set_position(&ivi->popup, + WESTON_LAYER_POSITION_TOP_UI); weston_layer_set_position(&ivi->fullscreen, WESTON_LAYER_POSITION_FULLSCREEN); @@ -467,8 +529,24 @@ static const struct agl_shell_interface agl_shell_implementation = { .activate_app = shell_activate_app, }; +static void +shell_desktop_set_app_property(struct wl_client *client, + struct wl_resource *shell_res, + const char *app_id, uint32_t role, + int x, int y, struct wl_resource *output_res) +{ + struct weston_head *head = weston_head_from_resource(output_res); + struct weston_output *woutput = weston_head_get_output(head); + struct ivi_output *output = to_ivi_output(woutput); + + /* temporary store the app_id such that, when created to be check against */ + if (role == AGL_SHELL_DESKTOP_APP_ROLE_POPUP) + ivi_set_pending_desktop_surface_popup(output, x, y, app_id); +} + static const struct agl_shell_desktop_interface agl_shell_desktop_implementation = { .activate_app = shell_activate_app, + .set_app_property = shell_desktop_set_app_property }; static void |