From 6a47c2243e604e44461ae915476f50d00eeafdf6 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Tue, 7 Nov 2017 13:52:31 +0900 Subject: efl ui win - make win centering work with multiple screens this should fix T6323 @fix --- src/lib/elementary/efl_ui_win.c | 46 ++++++++++++ src/modules/ecore_evas/engines/x/ecore_evas_x.c | 96 +++++++++++++++++++------ 2 files changed, 121 insertions(+), 21 deletions(-) diff --git a/src/lib/elementary/efl_ui_win.c b/src/lib/elementary/efl_ui_win.c index 4904a13e10..87e7e9624d 100644 --- a/src/lib/elementary/efl_ui_win.c +++ b/src/lib/elementary/efl_ui_win.c @@ -5595,6 +5595,52 @@ _efl_ui_win_center(Eo *obj, Efl_Ui_Win_Data *sd, Eina_Bool h, Eina_Bool v) if ((trap) && (trap->center) && (!trap->center(sd->trap_data, obj, h, v))) return; + if (!efl_gfx_visible_get(obj)) + { + // Chose to use env var so this will also translate more easily + // to wayland. yes - we can get x atoms to figure out if wm is + // enlightenment, but this works just as well. for wl we'd need + // an alternate wl specific way... this below works better IMHO + const char *s = getenv("DESKTOP"); + + if ((s) && (!strcasecmp(s, "Enlightenment"))) + { +#ifdef HAVE_ELEMENTARY_X + if (sd->x.xwin) + { + static Ecore_X_Atom state = 0; + static Ecore_X_Atom centered = 0; + + if (!centered) centered = ecore_x_atom_get + ("__E_ATOM_WINDOW_STATE_CENTERED"); + if (!state) state = ecore_x_atom_get + ("__E_ATOM_WINDOW_STATE"); + ecore_x_window_prop_card32_set(sd->x.xwin, state, ¢ered, 1); + } +#endif +// XXX: what to do with wayland? + return; + } + // not e - fall back to manually placing on what we think the screen + // is/will be... to do this move window to where pointer is first +#ifdef HAVE_ELEMENTARY_X + if (sd->x.xwin) + { + int x = 0, y = 0; + + if (sd->req_wh) + { + win_w = sd->req_w; + win_h = sd->req_h; + } + else evas_object_geometry_get(obj, NULL, NULL, &win_w, &win_h); + ecore_x_pointer_root_xy_get(&x, &y); + ecore_evas_move(sd->ee, x - (win_w / 2), y - (win_h / 2)); + } +#endif +// XXX: what to do with wayland? + } + ecore_evas_screen_geometry_get(sd->ee, &screen_x, &screen_y, &screen_w, &screen_h); diff --git a/src/modules/ecore_evas/engines/x/ecore_evas_x.c b/src/modules/ecore_evas/engines/x/ecore_evas_x.c index 542b3f82e9..88779a2a7c 100644 --- a/src/modules/ecore_evas/engines/x/ecore_evas_x.c +++ b/src/modules/ecore_evas/engines/x/ecore_evas_x.c @@ -3478,15 +3478,16 @@ _ecore_evas_x_avoid_damage_set(Ecore_Evas *ee, int on) } static void -_ecore_evas_x_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int *y, int *w, int *h) +_ecore_evas_x_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h) { - int outnum = 0; + int outnum = 0, i; int px = 0, py = 0, pw = 0, ph = 0; Ecore_X_Window root; Ecore_X_Randr_Output *out = NULL; Ecore_X_Randr_Crtc crtc; unsigned int val[4] = { 0 }; - + Eina_Bool found = EINA_FALSE; + if (ecore_x_window_prop_card32_get (ee->prop.window, ecore_x_atom_get("E_ZONE_GEOMETRY"), val, 4) == 4) { @@ -3496,7 +3497,7 @@ _ecore_evas_x_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int if (h) *h = (int)val[3]; return; } - + root = ecore_x_window_root_get(ee->prop.window); out = ecore_x_randr_window_outputs_get(ee->prop.window, &outnum); if (!out) @@ -3508,25 +3509,53 @@ norandr: ecore_x_window_size_get(root, w, h); return; } - crtc = ecore_x_randr_output_crtc_get(root, out[0]); - if (!crtc) goto norandr; - ecore_x_randr_crtc_geometry_get(root, crtc, &px, &py, &pw, &ph); - if ((pw == 0) || (ph == 0)) goto norandr; - if (x) *x = px; - if (y) *y = py; - if (w) *w = pw; - if (h) *h = ph; + for (i = 0; i < outnum; i++) + { + Eina_Rectangle winrect, outrect; + + crtc = ecore_x_randr_output_crtc_get(root, out[i]); + if (!crtc) continue; + ecore_x_randr_crtc_geometry_get(root, crtc, &px, &py, &pw, &ph); + if ((pw == 0) || (ph == 0)) continue; + if ((i == 0) || (ecore_x_randr_primary_output_get(root) == out[i])) + { + found = EINA_TRUE; + if (x) *x = px; + if (y) *y = py; + if (w) *w = pw; + if (h) *h = ph; + } + winrect.x = ee->x + (ee->w / 2); + winrect.y = ee->y + (ee->h / 2); + winrect.w = 1; + winrect.h = 1; + outrect.x = px; + outrect.y = py; + outrect.w = pw; + outrect.h = ph; + if (eina_rectangles_intersect(&outrect, &winrect)) + { + if (x) *x = px; + if (y) *y = py; + if (w) *w = pw; + if (h) *h = ph; + free(out); + return; + } + } free(out); + if (!found) goto norandr; } static void _ecore_evas_x_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi) { int scdpi, xmm = 0, ymm = 0, outnum = 0, w = 0, h = 0; - int px = 0, py = 0; + int px = 0, py = 0, i; Ecore_X_Window root; Ecore_X_Randr_Output *out = NULL; Ecore_X_Randr_Crtc crtc; + Eina_Bool found = EINA_FALSE; root = ecore_x_window_root_get(ee->prop.window); out = ecore_x_randr_window_outputs_get(ee->prop.window, &outnum); @@ -3539,15 +3568,40 @@ norandr: if (ydpi) *ydpi = scdpi; return; } - crtc = ecore_x_randr_output_crtc_get(root, out[0]); - if (!crtc) goto norandr; - ecore_x_randr_crtc_geometry_get(root, crtc, &px, &py, &w, &h); - if ((w == 0) || (h == 0)) goto norandr; - ecore_x_randr_output_size_mm_get(root, out[0], &xmm, &ymm); - if ((xmm == 0) || (ymm == 0)) goto norandr; - if (xdpi) *xdpi = (w * 254) / (xmm * 10); // 25.4mm / inch - if (ydpi) *ydpi = (h * 254) / (ymm * 10); // 25.4mm / inch + for (i = 0; i < outnum; i++) + { + Eina_Rectangle winrect, outrect; + + crtc = ecore_x_randr_output_crtc_get(root, out[i]); + if (!crtc) continue; + ecore_x_randr_crtc_geometry_get(root, crtc, &px, &py, &w, &h); + if ((w == 0) || (h == 0)) continue; + ecore_x_randr_output_size_mm_get(root, out[i], &xmm, &ymm); + if ((xmm == 0) || (ymm == 0)) continue; + if ((i == 0) || (ecore_x_randr_primary_output_get(root) == out[i])) + { + found = EINA_TRUE; + if (xdpi) *xdpi = (w * 254) / (xmm * 10); // 25.4mm / inch + if (ydpi) *ydpi = (h * 254) / (ymm * 10); // 25.4mm / inch + } + winrect.x = ee->x + (ee->w / 2); + winrect.y = ee->y + (ee->h / 2); + winrect.w = 1; + winrect.h = 1; + outrect.x = px; + outrect.y = py; + outrect.w = w; + outrect.h = h; + if (eina_rectangles_intersect(&outrect, &winrect)) + { + if (xdpi) *xdpi = (w * 254) / (xmm * 10); // 25.4mm / inch + if (ydpi) *ydpi = (h * 254) / (ymm * 10); // 25.4mm / inch + free(out); + return; + } + } free(out); + if (!found) goto norandr; } static void -- cgit v1.2.3