diff --git a/src/bin/e_comp_object.c b/src/bin/e_comp_object.c index 55c6dc43d..c42ec47d0 100644 --- a/src/bin/e_comp_object.c +++ b/src/bin/e_comp_object.c @@ -868,9 +868,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)) { @@ -929,6 +935,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); } } @@ -939,7 +948,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)) || @@ -1022,7 +1037,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 */ @@ -1033,6 +1052,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); @@ -2231,7 +2253,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)) { @@ -2847,6 +2873,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 aca2ba491..b13a63a33 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 643448517..fb8a77bd7 100644 --- a/src/bin/e_comp_x.c +++ b/src/bin/e_comp_x.c @@ -422,6 +422,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) { @@ -2125,6 +2127,11 @@ _e_comp_x_message(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Event_Cl } } #endif + else if (ev->message_type == ATM_GTK_FRAME_EXTENTS) + { + _e_comp_x_client_data_get(ec)->fetch_gtk_frame_extents = 1; + EC_CHANGED(ec); + } else DBG("missed client message '%s' for %u", ecore_x_atom_name_get(ev->message_type), ev->win); return ECORE_CALLBACK_PASS_ON; @@ -4288,6 +4295,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 (cd->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); + } + cd->fetch_gtk_frame_extents = 0; + } ec->changes.prop = 0; if (rem_change) e_remember_update(ec); if ((!cd->reparented) && (!ec->internal)) ec->changes.border = 0; diff --git a/src/bin/e_comp_x.h b/src/bin/e_comp_x.h index af1a01c9a..28da7b5a8 100644 --- a/src/bin/e_comp_x.h +++ b/src/bin/e_comp_x.h @@ -105,6 +105,7 @@ struct _E_Comp_X_Client_Data Eina_Bool frame_update : 1; Eina_Bool evas_init : 1; Eina_Bool unredirected_single : 1; + Eina_Bool fetch_gtk_frame_extents : 1; }; E_API Eina_Bool e_comp_x_init(void);