forked from enlightenment/enlightenment
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
This commit is contained in:
parent
d1454e4e1a
commit
b8322b2b0e
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue