e_client: add stay_within_margin signal 91/314591/1
authorSooChan Lim <sc1.lim@samsung.com>
Wed, 10 Jul 2024 11:38:34 +0000 (20:38 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Tue, 16 Jul 2024 04:19:37 +0000 (13:19 +0900)
Change-Id: I2c48e65c2a705500545883952bcdafccc7891df1

src/bin/core/e_client.c
src/bin/core/e_client_intern.h
src/bin/core/e_desk_area.c

index ea69b199a7a909ccb4ffbd20b44a91c5ea135ff8..f2b307c193a8ebd59484f7500632b0e4b199f647 100644 (file)
@@ -108,6 +108,7 @@ struct _E_Client_Private
         struct wl_signal delete_request;
         struct wl_signal kill_request;
         struct wl_signal ping;
+        struct wl_signal stay_within_margin;
      } events;
 
    Eina_Bool hide_by_request;
@@ -1027,6 +1028,7 @@ _e_client_private_init(E_Client *ec)
    wl_signal_init(&priv->events.delete_request);
    wl_signal_init(&priv->events.kill_request);
    wl_signal_init(&priv->events.ping);
+   wl_signal_init(&priv->events.stay_within_margin);
 
    e_object_data_set(E_OBJECT(ec), priv);
 
@@ -3739,16 +3741,9 @@ e_client_mouse_up(E_Client *ec, int button, Evas_Point *output, E_Binding_Event_
 E_API void
 e_client_stay_within_canvas_margin(E_Client *ec)
 {
-   int new_x = ec->x;
-   int new_y = ec->y;
-
-   if (ec->floating)
-     {
-        _e_client_stay_within_canvas_margin(ec, ec->x, ec->y, &new_x, &new_y);
+   API_ENTRY;
 
-        if ((ec->x != new_x) || (ec->y != new_y))
-          evas_object_move(ec->frame, new_x, new_y);
-     }
+   wl_signal_emit(&priv->events.stay_within_margin, NULL);
 }
 
 EINTERN void
@@ -7120,6 +7115,13 @@ e_client_ping_listener_add(E_Client *ec, struct wl_listener *listener)
    wl_signal_add(&priv->events.ping, listener);
 }
 
+EINTERN void
+e_client_stay_within_margin_listener_add(E_Client *ec, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.stay_within_margin, listener);
+}
+
 EINTERN void
 e_client_shell_configure_send(E_Client *ec, uint32_t edges, int32_t width, int32_t height)
 {
index 40fa38a5d3dc13e6a02c98815c525441e29d9434..ab1cd2337c953af5cee6f1fa00256565522fb7b0 100644 (file)
@@ -247,6 +247,7 @@ EINTERN void e_client_subsurface_stack_update_listener_add(E_Client *ec, struct
 EINTERN void e_client_delete_request_listener_add(E_Client *ec, struct wl_listener *listener);
 EINTERN void e_client_kill_request_listener_add(E_Client *ec, struct wl_listener *listener);
 EINTERN void e_client_ping_listener_add(E_Client *ec, struct wl_listener *listener);
+EINTERN void e_client_stay_within_margin_listener_add(E_Client *ec, struct wl_listener *listener);
 
 EINTERN struct wl_listener  *e_client_destroy_listener_get(E_Client *ec, wl_notify_func_t notify);
 
index 48a215b2a6ac700b0efd888d195db71dfe1c62aa..b82850043c99be4027294158e68b06a8e4fdba30 100644 (file)
@@ -80,6 +80,7 @@ struct _E_Desk_Area_Private_Client
    struct wl_listener client_maximize;
    struct wl_listener client_unmaximize;
    struct wl_listener client_activate_done;
+   struct wl_listener client_stay_within_margin;
    struct wl_listener delete_request;
    struct wl_listener kill_request;
    struct wl_listener ping;
@@ -739,6 +740,7 @@ _e_desk_area_private_client_del(E_Desk_Area_Private_Client *eda_client)
    wl_list_remove(&eda_client->comp_object_lower.link);
    wl_list_remove(&eda_client->comp_object_raise.link);
 
+   wl_list_remove(&eda_client->client_stay_within_margin.link);
    wl_list_remove(&eda_client->client_activate_done.link);
    wl_list_remove(&eda_client->client_unmaximize.link);
    wl_list_remove(&eda_client->client_maximize.link);
@@ -1837,6 +1839,136 @@ _desk_area_cb_client_redirect(struct wl_listener *listener, void *data)
      evas_object_resize(ec->frame, w, h);
 }
 
+static void
+_e_client_zones_layout_calc(E_Client *ec, int *zx, int *zy, int *zw, int *zh)
+{
+   int x, y, w, h;
+   E_Zone *zone_above, *zone_below, *zone_left, *zone_right;
+   E_Zone *zone;
+
+   zone = e_comp_zone_find_by_ec(ec);
+   if (!zone) return;
+   x = zone->x;
+   y = zone->y;
+   w = zone->w;
+   h = zone->h;
+
+   if (eina_list_count(e_comp->zones) == 1)
+     {
+        if (zx) *zx = x;
+        if (zy) *zy = y;
+        if (zw) *zw = w;
+        if (zh) *zh = h;
+        return;
+     }
+
+   zone_left = e_comp_zone_xy_get((x - w + 5), y);
+   zone_right = e_comp_zone_xy_get((x + w + 5), y);
+   zone_above = e_comp_zone_xy_get(x, (y - h + 5));
+   zone_below = e_comp_zone_xy_get(x, (y + h + 5));
+
+   if (!(zone_above) && (y))
+     zone_above = e_comp_zone_xy_get(x, (h - 5));
+
+   if (!(zone_left) && (x))
+     zone_left = e_comp_zone_xy_get((x - 5), y);
+
+   if (zone_right)
+     w = zone_right->x + zone_right->w;
+
+   if (zone_left)
+     w = zone->x + zone->w;
+
+   if (zone_below)
+     h = zone_below->y + zone_below->h;
+
+   if (zone_above)
+     h = zone->y + zone->h;
+
+   if ((zone_left) && (zone_right))
+     w = zone->w + zone_right->x;
+
+   if ((zone_above) && (zone_below))
+     h = zone->h + zone_below->y;
+
+   if (x) x -= zone->w;
+   if (y) y -= zone->h;
+
+   if (zx) *zx = x > 0 ? x : 0;
+   if (zy) *zy = y > 0 ? y : 0;
+   if (zw) *zw = w;
+   if (zh) *zh = h;
+}
+
+static void
+_e_client_stay_within_canvas_margin(E_Client *ec, int x, int y, int *new_x, int *new_y)
+{
+   // TODO: FIXME: fix the x, y in Desk_Area
+   int new_x_max, new_y_max, new_x_min, new_y_min;
+   int margin_w, margin_h;
+   int zw = 0, zh = 0;
+   int cw, ch;
+   E_Zone *zone;
+
+   zone = e_comp_zone_find_by_ec(ec);
+   if (!zone)
+     {
+        if (new_x) *new_x = x;
+        if (new_y) *new_y = y;
+        return;
+     }
+
+   cw = ec->w;
+   ch = ec->h;
+
+   _e_client_zones_layout_calc(ec, NULL, NULL, &zw, &zh);
+
+   margin_w = zw/3;
+   margin_h = zh/10;
+
+   new_x_min = (margin_w > cw) ? 0 : -(cw - margin_w);
+   new_x_max = (margin_w > cw) ? (zw - cw) : (zw - margin_w);
+   new_y_min = (margin_h > ch) ? 0 : -(ch - margin_h);
+   new_y_max = (margin_h > ch) ? (zh - ch) : (zh - margin_h);
+
+   if (x >= new_x_max)
+     *new_x = new_x_max;
+   else if (x <= new_x_min)
+     *new_x = new_x_min;
+
+   if (y >= new_y_max)
+     *new_y = new_y_max;
+   else if (y <= new_y_min)
+     *new_y = new_y_min;
+
+}
+
+static void
+_desk_area_cb_client_stay_within_margin(struct wl_listener *listener, void *data)
+{
+   E_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+   int new_x, new_y;
+
+   eda_client = wl_container_of(listener, eda_client, client_stay_within_margin);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   ELOGF("EDA", "CLIENT STAY WITHIN MARGIN. eda:%p", ec, eda);
+
+   new_x = ec->x;
+   new_y = ec->y;
+
+   if (ec->floating)
+     {
+        _e_client_stay_within_canvas_margin(ec, ec->x, ec->y, &new_x, &new_y);
+
+        if ((ec->x != new_x) || (ec->y != new_y))
+          evas_object_move(ec->frame, new_x, new_y);
+     }
+}
+
 static void
 _desk_area_cb_comp_object_lower(struct wl_listener *listener, void *data)
 {
@@ -2442,6 +2574,8 @@ e_desk_area_ec_add(E_Desk_Area *eda, E_Client *ec)
    e_client_unmaximize_listener_add(ec, &eda_client->client_unmaximize);
    eda_client->client_activate_done.notify = _desk_area_cb_client_activate_done;
    e_client_activate_done_listener_add(ec, &eda_client->client_activate_done);
+   eda_client->client_stay_within_margin.notify = _desk_area_cb_client_stay_within_margin;
+   e_client_stay_within_margin_listener_add(ec, &eda_client->client_stay_within_margin);
 
    // e_comp_object listeners
    eda_client->comp_object_lower.notify = _desk_area_cb_comp_object_lower;