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;
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);
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
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)
{
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;
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);
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)
{
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;