grpc-proxy: Add dynamic floating window movement 68/29068/2
authorMarius Vlad <marius.vlad@collabora.com>
Thu, 27 Jul 2023 13:37:15 +0000 (16:37 +0300)
committerMarius Vlad <marius.vlad@collabora.com>
Tue, 29 Aug 2023 13:31:20 +0000 (13:31 +0000)
This adds basic movement for floating type of windows. The window needs
to be a floating type for this request to work out.

For the agl-shell protocol, this adds a set_app_float() request while
for gRPC it adds a SetAppPosition() request.

Bug-AGL: SPEC-4863
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Change-Id: I5ecc4257c3e84d15a8cabb183757753be37867f5

grpc-proxy/agl_shell.proto
grpc-proxy/grpc-async-cb.cpp
grpc-proxy/grpc-async-cb.h
grpc-proxy/main-grpc.cpp
grpc-proxy/shell.cpp
grpc-proxy/shell.h
protocol/agl-shell.xml
src/shell.c

index aac35f4..74ea958 100644 (file)
@@ -13,6 +13,7 @@ service AglShellManagerService {
        rpc GetOutputs(OutputRequest)                           returns (ListOutputResponse) {}
        rpc SetAppNormal(NormalRequest)                         returns (NormalResponse) {}
        rpc SetAppOnOutput(AppOnOutputRequest)                  returns (AppOnOutputResponse) {}
        rpc GetOutputs(OutputRequest)                           returns (ListOutputResponse) {}
        rpc SetAppNormal(NormalRequest)                         returns (NormalResponse) {}
        rpc SetAppOnOutput(AppOnOutputRequest)                  returns (AppOnOutputResponse) {}
+       rpc SetAppPosition(AppPositionRequest)                  returns (AppPositionResponse) {}
 }
 
 message ActivateRequest {
 }
 
 message ActivateRequest {
@@ -23,6 +24,7 @@ message ActivateRequest {
 message ActivateResponse {
 };
 
 message ActivateResponse {
 };
 
+
 message DeactivateRequest {
        string app_id = 1;
 }
 message DeactivateRequest {
        string app_id = 1;
 }
@@ -87,3 +89,12 @@ message AppOnOutputRequest {
 
 message AppOnOutputResponse {
 };
 
 message AppOnOutputResponse {
 };
+
+message AppPositionRequest {
+       string app_id = 1;
+       int32 x = 2;
+       int32 y = 3;
+};
+
+message AppPositionResponse {
+};
index 1bb367a..92aaa3c 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright © 2022 Collabora, Ltd.
+ * Copyright © 2022, 2023 Collabora, Ltd.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
@@ -158,6 +158,18 @@ GrpcServiceImpl::SetAppOnOutput(grpc::CallbackServerContext *context,
        return reactor;
 }
 
        return reactor;
 }
 
+grpc::ServerUnaryReactor *
+GrpcServiceImpl::SetAppPosition(grpc::CallbackServerContext *context,
+                            const ::agl_shell_ipc::AppPositionRequest* request,
+                            ::agl_shell_ipc::AppPositionResponse* /* response */)
+{
+       m_aglShell->SetAppPosition(request->app_id(), request->x(), request->y());
+
+       grpc::ServerUnaryReactor* reactor = context->DefaultReactor();
+       reactor->Finish(grpc::Status::OK);
+       return reactor;
+}
+
 grpc::ServerUnaryReactor *
 GrpcServiceImpl::SetAppSplit(grpc::CallbackServerContext *context,
            const ::agl_shell_ipc::SplitRequest* request,
 grpc::ServerUnaryReactor *
 GrpcServiceImpl::SetAppSplit(grpc::CallbackServerContext *context,
            const ::agl_shell_ipc::SplitRequest* request,
index 4987cf7..21a4e4d 100644 (file)
@@ -96,6 +96,10 @@ public:
                        const ::agl_shell_ipc::AppOnOutputRequest* request,
                        ::agl_shell_ipc::AppOnOutputResponse* /*response*/) override;
 
                        const ::agl_shell_ipc::AppOnOutputRequest* request,
                        ::agl_shell_ipc::AppOnOutputResponse* /*response*/) override;
 
+       grpc::ServerUnaryReactor *SetAppPosition(grpc::CallbackServerContext *context,
+                       const ::agl_shell_ipc::AppPositionRequest* request,
+                       ::agl_shell_ipc::AppPositionResponse* /*response*/) override;
+
        grpc::ServerWriteReactor< ::agl_shell_ipc::AppStateResponse>* AppStatusState(
              ::grpc::CallbackServerContext* /*context*/,
              const ::agl_shell_ipc::AppStateRequest* /*request*/)  override;
        grpc::ServerWriteReactor< ::agl_shell_ipc::AppStateResponse>* AppStatusState(
              ::grpc::CallbackServerContext* /*context*/,
              const ::agl_shell_ipc::AppStateRequest* /*request*/)  override;
index 1e297c5..740594f 100644 (file)
@@ -275,7 +275,7 @@ global_add(void *data, struct wl_registry *reg, uint32_t id,
                sh->shell =
                        static_cast<struct agl_shell *>(wl_registry_bind(reg, id,
                                &agl_shell_interface,
                sh->shell =
                        static_cast<struct agl_shell *>(wl_registry_bind(reg, id,
                                &agl_shell_interface,
-                               std::min(static_cast<uint32_t>(8), version)));
+                               std::min(static_cast<uint32_t>(9), version)));
                agl_shell_add_listener(sh->shell, &shell_listener, data);
                sh->version = version;
        } else if (strcmp(interface, "wl_output") == 0) {
                agl_shell_add_listener(sh->shell, &shell_listener, data);
                sh->version = version;
        } else if (strcmp(interface, "wl_output") == 0) {
@@ -299,7 +299,7 @@ global_add_init(void *data, struct wl_registry *reg, uint32_t id,
                sh->shell =
                        static_cast<struct agl_shell *>(wl_registry_bind(reg, id,
                                &agl_shell_interface,
                sh->shell =
                        static_cast<struct agl_shell *>(wl_registry_bind(reg, id,
                                &agl_shell_interface,
-                               std::min(static_cast<uint32_t>(8), version)));
+                               std::min(static_cast<uint32_t>(9), version)));
                agl_shell_add_listener(sh->shell, &shell_listener_init, data);
                sh->version = version;
        }
                agl_shell_add_listener(sh->shell, &shell_listener_init, data);
                sh->version = version;
        }
index 34f6d37..44f2117 100644 (file)
@@ -120,6 +120,15 @@ Shell::SetAppOnOutput(const std::string &app_id, const std::string &output)
        wl_display_flush(m_shell_data->wl_display);
 }
 
        wl_display_flush(m_shell_data->wl_display);
 }
 
+void
+Shell::SetAppPosition(const std::string &app_id, const int32_t x, const int32_t y)
+{
+       struct agl_shell *shell = this->m_shell.get();
+
+       agl_shell_set_app_position(shell, app_id.c_str(), x, y);
+       wl_display_flush(m_shell_data->wl_display);
+}
+
 void
 Shell::SetAppSplit(const std::string &app_id, uint32_t orientation)
 {
 void
 Shell::SetAppSplit(const std::string &app_id, uint32_t orientation)
 {
index b047eef..b9a818c 100644 (file)
@@ -46,4 +46,5 @@ public:
        void SetAppNormal(const std::string &app_id);
        void SetAppFullscreen(const std::string &app_id);
        void SetAppOnOutput(const std::string &app_id, const std::string &output);
        void SetAppNormal(const std::string &app_id);
        void SetAppFullscreen(const std::string &app_id);
        void SetAppOnOutput(const std::string &app_id, const std::string &output);
+       void SetAppPosition(const std::string &app_id, int32_t x, int32_t y);
 };
 };
index e010a80..b85cf01 100644 (file)
@@ -22,7 +22,7 @@
     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     DEALINGS IN THE SOFTWARE.
   </copyright>
     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     DEALINGS IN THE SOFTWARE.
   </copyright>
-  <interface name="agl_shell" version="8">
+  <interface name="agl_shell" version="9">
     <description summary="user interface for Automotive Grade Linux platform">
       Starting with version 2 of the protocol, the client is required to wait
       for the 'bound_ok' or 'bound_fail' events in order to proceed further.
     <description summary="user interface for Automotive Grade Linux platform">
       Starting with version 2 of the protocol, the client is required to wait
       for the 'bound_ok' or 'bound_fail' events in order to proceed further.
     </request>
 
     <request name="set_app_output" since="8">
     </request>
 
     <request name="set_app_output" since="8">
-      <description summary="Assign an application to a particular output">
-        This would allow the compositor to place an application on a particular
-        output, if that output is indeed available. This can happen before
+      <description summary="assign an application to a particular output">
+        this would allow the compositor to place an application on a particular
+        output, if that output is indeed available. this can happen before
         application is started which would make the application start on that
         application is started which would make the application start on that
-        particular output. If the application is already started it would
+        particular output. if the application is already started it would
         move the application to that output.
 
         move the application to that output.
 
-        There's no persistence of this request, once the application terminated
+        there's no persistence of this request, once the application terminated
         you'll need to issue this request again for that particular app_id.
 
         you'll need to issue this request again for that particular app_id.
 
-        See xdg_toplevel.set_app_id from the xdg-shell protocol for a
+        see xdg_toplevel.set_app_id from the xdg-shell protocol for a
         description of app_id.
       </description>
       <arg name="app_id" type="string"/>
         description of app_id.
       </description>
       <arg name="app_id" type="string"/>
       <arg name="app_id" type="string"/>
       <arg name="output_name" type="string"/>
     </event>
       <arg name="app_id" type="string"/>
       <arg name="output_name" type="string"/>
     </event>
+
+    <request name="set_app_position" since="9">
+      <description summary="move window to a specific position">
+        Clients can inform the compositor to position a floating type of window
+        at the specific location, pointed by x and y value. If the window is
+        not a floating type, the request will be discarded. Note that
+        positioning doesn't take output into consideration nor does orientation
+        of the outpus. It is expected that the client knows already where the
+        position is localed in global coordonate space. If the window doesn't
+        exist the compositor will ignore the request. For this request to
+        function properly the window would first to be set as floating and then
+        it can be moved using this request.
+
+        see xdg_toplevel.set_app_id from the xdg-shell protocol for a
+        description of app_id.
+      </description>
+      <arg name="app_id" type="string"/>
+      <arg name="x" type="int"/>
+      <arg name="y" type="int"/>
+    </request>
   </interface>
 
   <interface name="agl_shell_ext" version="1">
   </interface>
 
   <interface name="agl_shell_ext" version="1">
index 1aabb5a..2ce6ac4 100644 (file)
@@ -1664,6 +1664,20 @@ shell_set_app_output(struct wl_client *client, struct wl_resource *res,
        shell_send_app_on_output(ivi, app_id, woutput->name);
 }
 
        shell_send_app_on_output(ivi, app_id, woutput->name);
 }
 
+static void
+shell_set_app_position(struct wl_client *client, struct wl_resource *res,
+                   const char *app_id, int32_t x, int32_t y)
+{
+       struct ivi_compositor *ivi = wl_resource_get_user_data(res);
+       struct ivi_surface *surf = ivi_find_app(ivi, app_id);
+
+       if (!surf || !app_id || surf->role != IVI_SURFACE_ROLE_POPUP)
+               return;
+
+       weston_view_set_position(surf->view, x, y);
+       weston_compositor_schedule_repaint(ivi->compositor);
+}
+
 static void
 shell_ext_destroy(struct wl_client *client, struct wl_resource *res)
 {
 static void
 shell_ext_destroy(struct wl_client *client, struct wl_resource *res)
 {
@@ -1692,6 +1706,7 @@ static const struct agl_shell_interface agl_shell_implementation = {
        .set_app_normal = shell_set_app_normal,
        .set_app_fullscreen = shell_set_app_fullscreen,
        .set_app_output = shell_set_app_output,
        .set_app_normal = shell_set_app_normal,
        .set_app_fullscreen = shell_set_app_fullscreen,
        .set_app_output = shell_set_app_output,
+       .set_app_position = shell_set_app_position,
 };
 
 static const struct agl_shell_ext_interface agl_shell_ext_implementation = {
 };
 
 static const struct agl_shell_ext_interface agl_shell_ext_implementation = {
@@ -1993,7 +2008,7 @@ int
 ivi_shell_create_global(struct ivi_compositor *ivi)
 {
        ivi->agl_shell = wl_global_create(ivi->compositor->wl_display,
 ivi_shell_create_global(struct ivi_compositor *ivi)
 {
        ivi->agl_shell = wl_global_create(ivi->compositor->wl_display,
-                                         &agl_shell_interface, 8,
+                                         &agl_shell_interface, 9,
                                          ivi, bind_agl_shell);
        if (!ivi->agl_shell) {
                weston_log("Failed to create wayland global.\n");
                                          ivi, bind_agl_shell);
        if (!ivi->agl_shell) {
                weston_log("Failed to create wayland global.\n");