summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/desktop.c17
-rw-r--r--src/ivi-compositor.h30
-rw-r--r--src/layout.c38
-rw-r--r--src/main.c1
-rw-r--r--src/shell.c78
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;
diff --git a/src/main.c b/src/main.c
index deef8bc..df97b24 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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