discomfitor pushed a commit to branch enlightenment-0.19.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=53e0c56f5eb14eee733639f8b5344ccc219e6f16

commit 53e0c56f5eb14eee733639f8b5344ccc219e6f16
Author: Mike Blumenkrantz <zm...@osg.samsung.com>
Date:   Thu Sep 24 15:29:37 2015 -0400

    fully support _GTK_FRAME_EXTENTS
    
    gtk apps set an atom which provides information about the area
    where non-window content (eg. shadows) may be drawn; this area
    must not be used in placement calculations.
    
    the easiest method for implementing this functionality was to add
    a case to the compositor geometry interceptors which effectively
    flip the client struct geometry values such that the E_Client->client
    is outside of the more commonly used E_Client->x/y/w/h
    
    fix T2744
---
 src/bin/e_comp_object.c | 52 ++++++++++++++++++++++++++++++++++++++++++++-----
 src/bin/e_comp_object.h |  1 +
 src/bin/e_comp_x.c      | 30 ++++++++++++++++++++++++++++
 src/bin/e_comp_x.h      |  1 +
 4 files changed, 79 insertions(+), 5 deletions(-)

diff --git a/src/bin/e_comp_object.c b/src/bin/e_comp_object.c
index 52b1e8f..98ca8a9 100644
--- a/src/bin/e_comp_object.c
+++ b/src/bin/e_comp_object.c
@@ -760,9 +760,15 @@ static void
 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
 {
    E_Comp_Object *cw = data;
-   int ix, iy;
+   int ix, iy, fx, fy;
 
-   if ((cw->x == x) && (cw->y == y))
+   /* if frame_object does not exist, client_inset indicates CSD.
+    * this means that ec->client matches cw->x/y, the opposite
+    * of SSD.
+    */
+   fx = (!cw->frame_object) * cw->client_inset.l;
+   fy = (!cw->frame_object) * cw->client_inset.t;
+   if ((cw->x == x + fx) && (cw->y == y + fy))
      {
         if ((cw->ec->x != x) || (cw->ec->y != y))
           {
@@ -821,6 +827,9 @@ _e_comp_intercept_move(void *data, Evas_Object *obj, int x, 
int y)
              cw->ec->client.x = ix;
              cw->ec->client.y = iy;
           }
+        /* flip SSD->CSD */
+        if (!cw->frame_object)
+          x = ix, y = iy;
         evas_object_move(obj, x, y);
      }
 }
@@ -831,7 +840,13 @@ _e_comp_intercept_resize(void *data, Evas_Object *obj, int 
w, int h)
    E_Comp_Object *cw = data;
    int pw, ph, fw, fh, iw, ih, prev_w, prev_h;
 
-   if ((cw->w == w) && (cw->h == h))
+   /* if frame_object does not exist, client_inset indicates CSD.
+    * this means that ec->client matches cw->w/h, the opposite
+    * of SSD.
+    */
+   fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
+   fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
+   if ((cw->w == w + fw) && (cw->h == h + fh))
      {
         if (cw->ec->shading || cw->ec->shaded) return;
         if (((cw->ec->w != w) || (cw->ec->h != h)) ||
@@ -913,7 +928,11 @@ _e_comp_intercept_resize(void *data, Evas_Object *obj, int 
w, int h)
      {
         //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
         evas_object_smart_callback_call(obj, "client_resize", NULL);
-        e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
+        /* flip for CSD */
+        if (cw->frame_object || cw->ec->input_only)
+          e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
+        else
+          w = pw, h = ph;
         if ((cw->w == w) && (cw->h == h))
           {
              /* going to be a noop resize which won't trigger smart resize */
@@ -924,6 +943,9 @@ _e_comp_intercept_resize(void *data, Evas_Object *obj, int 
w, int h)
      }
    else
      {
+        /* flip for CSD */
+        if ((!cw->frame_object) && (!cw->ec->input_only))
+          w = pw, h = ph;
         /* "just do it" for overrides */
         //INF("INTERCEPT %dx%d", w, h);
         evas_object_resize(obj, w, h);
@@ -2086,7 +2108,11 @@ _e_comp_smart_resize(Evas_Object *obj, int w, int h)
    if ((!cw->ec->shading) && (!cw->ec->shaded))
      {
         int ww, hh, pw, ph;
-        e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
+
+        if (cw->frame_object)
+          e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
+        else
+          ww = w, hh = h;
         /* verify pixmap:object size */
         if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
           {
@@ -2741,6 +2767,22 @@ e_comp_object_frame_geometry_get(Evas_Object *obj, int 
*l, int *r, int *t, int *
    if (b) *b = cw->client_inset.b;
 }
 
+/* set geometry for CSD */
+E_API void
+e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
+{
+   API_ENTRY;
+   cw->client_inset.l = l;
+   cw->client_inset.r = r;
+   cw->client_inset.t = t;
+   cw->client_inset.b = b;
+   cw->client_inset.calc = 1;
+   eina_stringshare_replace(&cw->frame_theme, "borderless");
+   if (!cw->ec->new_client) return;
+   cw->ec->w += l + r;
+   cw->ec->h += t + b;
+}
+
 E_API void
 e_comp_object_frame_icon_geometry_get(Evas_Object *obj, int *x, int *y, int 
*w, int *h)
 {
diff --git a/src/bin/e_comp_object.h b/src/bin/e_comp_object.h
index adc8d27..93fde27 100644
--- a/src/bin/e_comp_object.h
+++ b/src/bin/e_comp_object.h
@@ -54,6 +54,7 @@ E_API void e_comp_object_util_center_on(Evas_Object *obj, 
Evas_Object *on);
 E_API void e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y);
 E_API void e_comp_object_util_fullscreen(Evas_Object *obj);
 E_API void e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, 
int *t, int *b);
+E_API void e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, 
int t, int b);
 E_API void e_comp_object_frame_icon_geometry_get(Evas_Object *obj, int *x, int 
*y, int *w, int *h);
 E_API Eina_Bool e_comp_object_frame_title_set(Evas_Object *obj, const char 
*name);
 E_API Eina_Bool e_comp_object_frame_exists(Evas_Object *obj);
diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c
index 3717654..2614a62 100644
--- a/src/bin/e_comp_x.c
+++ b/src/bin/e_comp_x.c
@@ -398,6 +398,8 @@ _e_comp_x_client_new_helper(E_Client *ec)
              /* loop to check for window profile list atom */
              else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED)
                ec->e.fetch.profile = 1;
+             else if (atoms[i] == ATM_GTK_FRAME_EXTENTS)
+               ec->comp_data->fetch_gtk_frame_extents = 1;
           }
         if (video_position && video_parent)
           {
@@ -2028,6 +2030,11 @@ _e_comp_x_message(void *data EINA_UNUSED, int type 
EINA_UNUSED, Ecore_X_Event_Cl
              free(p);
           }
      }
+   else if (ev->message_type == ATM_GTK_FRAME_EXTENTS)
+     {
+        ec->comp_data->fetch_gtk_frame_extents = 1;
+        EC_CHANGED(ec);
+     }
    return ECORE_CALLBACK_PASS_ON;
 }
 
@@ -4199,6 +4206,29 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, 
E_Client *ec)
         ec->e.state.profile.wait_for_done = 1;
         eina_stringshare_replace(&ec->e.state.profile.set, NULL);
      }
+   if (ec->comp_data->fetch_gtk_frame_extents)
+     {
+        unsigned char *data;
+        int count;
+
+        if (ecore_x_window_prop_property_get(win,
+                                             ATM_GTK_FRAME_EXTENTS,
+                                             ECORE_X_ATOM_CARDINAL, 32,
+                                             &data, &count))
+          {
+             unsigned int *extents = (unsigned int*)data;
+
+             /* _GTK_FRAME_EXTENTS describes a region l/r/t/b pixels
+              * from the "window" object in which shadows will be drawn.
+              * this area should not be accounted for in sizing or
+              * placement calculations.
+              */
+             e_comp_object_frame_geometry_set(ec->frame,
+               -extents[0], -extents[1], -extents[2], -extents[3]);
+             free(data);
+          }
+        ec->comp_data->fetch_gtk_frame_extents = 0;
+     }
    ec->changes.prop = 0;
    if (rem_change) e_remember_update(ec);
    if ((!ec->comp_data->reparented) && (!ec->internal)) ec->changes.border = 0;
diff --git a/src/bin/e_comp_x.h b/src/bin/e_comp_x.h
index 1de8c24..033f31a 100644
--- a/src/bin/e_comp_x.h
+++ b/src/bin/e_comp_x.h
@@ -106,6 +106,7 @@ struct _E_Comp_X_Client_Data
    Eina_Bool evas_init : 1;
    Eina_Bool unredirected_single : 1;
    unsigned int parent_activate_count; //number of times a win has activated 
itself when parent was focused
+   Eina_Bool fetch_gtk_frame_extents : 1;
 };
 
 EINTERN Eina_Bool e_comp_x_init(void);

-- 


Reply via email to