protocol, grpc-proxy: Add support for set_app_float
[src/agl-compositor.git] / src / shell.c
index d9d3c2d..4a1a954 100644 (file)
@@ -1088,7 +1088,8 @@ create_black_curtain_view(struct ivi_output *output)
 bool
 output_has_black_curtain(struct ivi_output *output)
 {
-       return (output->fullscreen_view.fs->view &&
+       return (output->fullscreen_view.fs &&
+               output->fullscreen_view.fs->view &&
                output->fullscreen_view.fs->view->is_mapped &&
                output->fullscreen_view.fs->view->surface->is_mapped);
 }
@@ -1409,10 +1410,20 @@ shell_activate_app(struct wl_client *client,
                   const char *app_id,
                   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_compositor *ivi = wl_resource_get_user_data(shell_res);
-       struct ivi_output *output = to_ivi_output(woutput);
+       struct weston_head *head;
+       struct weston_output *woutput;
+       struct ivi_compositor *ivi;
+       struct ivi_output *output;
+
+       head = weston_head_from_resource(output_res);
+       if (!head) {
+               weston_log("Invalid output to activate '%s' on\n", app_id);
+               return;
+       }
+
+       woutput = weston_head_get_output(head);
+       ivi = wl_resource_get_user_data(shell_res);
+       output = to_ivi_output(woutput);
 
        if (wl_resource_get_version(shell_res) >=
            AGL_SHELL_BOUND_OK_SINCE_VERSION &&
@@ -1427,6 +1438,72 @@ shell_activate_app(struct wl_client *client,
        ivi_layout_activate(output, app_id);
 }
 
+static void
+shell_new_deactivate_app(struct wl_client *client, struct wl_resource *shell_res,
+                        const char *app_id)
+{
+       struct ivi_compositor *ivi = wl_resource_get_user_data(shell_res);
+
+       ivi_layout_deactivate(ivi, app_id);
+}
+
+static void
+shell_set_app_float(struct wl_client *client, struct wl_resource *shell_res,
+                  const char *app_id, int32_t x_pos, int32_t y_pos)
+{
+       struct ivi_compositor *ivi = wl_resource_get_user_data(shell_res);
+       struct weston_output *output = get_focused_output(ivi->compositor);
+       struct ivi_output *ivi_output;
+       struct ivi_surface *surf = ivi_find_app(ivi, app_id);
+
+       if (!output)
+               output = get_default_output(ivi->compositor);
+
+       ivi_output = to_ivi_output(output);
+
+       /* verify if already mapped as desktop role, regular, unmap it, so we
+        * can make it float */
+       if (surf && surf->role == IVI_SURFACE_ROLE_DESKTOP) {
+               struct weston_view *ev = surf->view;
+               struct weston_desktop_surface *dsurf = surf->dsurface;
+               struct ivi_bounding_box bb = {};
+
+               /* XXX: if this is useful we could bring it as active then make
+                * it float, but avoid doing it for the moment */
+               if (surf != ivi_output->active)
+                       return;
+
+               ivi_layout_deactivate(ivi, app_id);
+               surf->hidden_layer_output = ivi_output;
+
+               /* set attributes */
+               surf->popup.output = ivi_output;
+
+               surf->popup.x = x_pos;
+               surf->popup.y = y_pos;
+               surf->popup.bb = bb;
+
+               /* change the role */
+               surf->role = IVI_SURFACE_ROLE_NONE;
+
+               wl_list_remove(&surf->link);
+               wl_list_init(&surf->link);
+
+               ivi_set_desktop_surface_popup(surf);
+
+               weston_desktop_surface_set_maximized(dsurf, false);
+               weston_desktop_surface_set_size(dsurf, 0, 0);
+
+               /* add to hidden layer */
+               weston_layer_entry_insert(&ivi->hidden.view_list, &ev->layer_link);
+               weston_compositor_schedule_repaint(ivi->compositor);
+
+       } else if (!surf || (surf && surf->role != IVI_SURFACE_ROLE_POPUP)) {
+               ivi_set_pending_desktop_surface_popup(ivi_output, x_pos, y_pos, 
+                                                     0, 0, 0, 0, app_id);
+       }
+}
+
 static void
 shell_desktop_activate_app(struct wl_client *client,
                           struct wl_resource *shell_res,
@@ -1507,7 +1584,9 @@ static const struct agl_shell_interface agl_shell_implementation = {
        .set_panel = shell_set_panel,
        .activate_app = shell_activate_app,
        .destroy = shell_destroy,
-       .set_activate_region = shell_set_activate_region
+       .set_activate_region = shell_set_activate_region,
+       .deactivate_app = shell_new_deactivate_app,
+       .set_app_float = shell_set_app_float,
 };
 
 static const struct agl_shell_ext_interface agl_shell_ext_implementation = {
@@ -1611,6 +1690,8 @@ unbind_agl_shell(struct wl_resource *resource)
        }
 
        wl_list_for_each(output, &ivi->outputs, link) {
+               struct weston_geometry area = {};
+
                /* reset the active surf if there's one present */
                if (output->active) {
                        output->active->view->is_mapped = false;
@@ -1620,6 +1701,7 @@ unbind_agl_shell(struct wl_resource *resource)
                        output->active = NULL;
                }
 
+               output->area_activation = area;
                insert_black_curtain(output);
        }
 
@@ -1804,7 +1886,7 @@ int
 ivi_shell_create_global(struct ivi_compositor *ivi)
 {
        ivi->agl_shell = wl_global_create(ivi->compositor->wl_display,
-                                         &agl_shell_interface, 4,
+                                         &agl_shell_interface, 6,
                                          ivi, bind_agl_shell);
        if (!ivi->agl_shell) {
                weston_log("Failed to create wayland global.\n");