From 372bf108a7b0213bdaf78af9b27a4d0180134f50 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Mon, 20 Nov 2017 17:28:20 +0900 Subject: [PATCH] win: Make wm_available_rotations simpler for EO The problem with the API is that it uses an array of ints, which is not well defined in EO. We could set an array of pointers to int, but that would be super awkward to use. I believe the original API has been slightly over-engineered as it was passing an array of available rotations when in reality only 4 rotations could be supported (0, 90, 180, 270). It seems to me that the day arbitrary rotation needs to be allowed, another API would be required (maybe with a range, or a single bool flag to allow anything). I have not modified the internal code, which still uses an array (as ecore evas uses that). Mote: ec464939d9b8e4daa removed wm_rotation_supported_get(), as well as the preferred rotation from EO, but they could easily be added back if needed. Note 2: I couldn't test as desktop E doesn't support WM rotations. Ref T5322 --- src/lib/elementary/efl_ui_win.c | 109 +++++++++++++++++++++------- src/lib/elementary/efl_ui_win.eo | 41 ++++------- src/lib/elementary/elm_win_legacy.h | 33 +++++++++ 3 files changed, 131 insertions(+), 52 deletions(-) diff --git a/src/lib/elementary/efl_ui_win.c b/src/lib/elementary/efl_ui_win.c index 4ab637dd9a..d80a20148d 100644 --- a/src/lib/elementary/efl_ui_win.c +++ b/src/lib/elementary/efl_ui_win.c @@ -6209,56 +6209,113 @@ _win_rotate(Evas_Object *obj, Efl_Ui_Win_Data *sd, int rotation, Eina_Bool resiz } EOLIAN static void -_efl_ui_win_wm_available_rotations_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const int *rotations, unsigned int count) +_efl_ui_win_wm_available_rotations_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, + Eina_Bool allow_0, Eina_Bool allow_90, + Eina_Bool allow_180, Eina_Bool allow_270) { - unsigned int i; - int r; + unsigned cnt = 0; + int rots[4]; - if (!sd->wm_rot.use) - sd->wm_rot.use = EINA_TRUE; + if (allow_0) rots[cnt++] = 0; + if (allow_90) rots[cnt++] = 90; + if (allow_180) rots[cnt++] = 180; + if (allow_270) rots[cnt++] = 270; + sd->wm_rot.use = EINA_TRUE; ELM_SAFE_FREE(sd->wm_rot.rots, free); sd->wm_rot.count = 0; - if (count > 0) + if (cnt) { - sd->wm_rot.rots = calloc(count, sizeof(int)); + sd->wm_rot.rots = malloc(sizeof(int) * cnt); if (!sd->wm_rot.rots) return; - for (i = 0; i < count; i++) - { - r = _win_rotation_degree_check(rotations[i]); - sd->wm_rot.rots[i] = r; - } + memcpy(sd->wm_rot.rots, rots, cnt * sizeof(int)); + sd->wm_rot.count = cnt; } - sd->wm_rot.count = count; - ecore_evas_wm_rotation_available_rotations_set(sd->ee, sd->wm_rot.rots, sd->wm_rot.count); } EOLIAN static Eina_Bool -_efl_ui_win_wm_available_rotations_get(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, int **rotations, unsigned int *count) +_efl_ui_win_wm_available_rotations_get(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, + Eina_Bool *allow_0, Eina_Bool *allow_90, + Eina_Bool *allow_180, Eina_Bool *allow_270) { - if (!sd->wm_rot.use) return EINA_FALSE; + if (!sd->wm_rot.use) goto end; - if (sd->wm_rot.count > 0) + if (allow_0) *allow_0 = EINA_FALSE; + if (allow_90) *allow_90 = EINA_FALSE; + if (allow_180) *allow_180 = EINA_FALSE; + if (allow_270) *allow_270 = EINA_FALSE; + + for (unsigned k = 0; k < sd->wm_rot.count; k++) { - if (rotations) + switch (sd->wm_rot.rots[k]) { - *rotations = calloc(sd->wm_rot.count, sizeof(int)); - if (*rotations) - { - memcpy(*rotations, - sd->wm_rot.rots, - sizeof(int) * sd->wm_rot.count); - } + case 0: if (allow_0) *allow_0 = EINA_TRUE; break; + case 90: if (allow_90) *allow_90 = EINA_TRUE; break; + case 180: if (allow_180) *allow_180 = EINA_TRUE; break; + case 270: if (allow_270) *allow_270 = EINA_TRUE; break; + default: ERR("Unsupported rotation %d", sd->wm_rot.rots[k]); break; } } - if (count) *count = sd->wm_rot.count; +end: + return !!sd->wm_rot.use; +} + +EAPI void +elm_win_wm_rotation_available_rotations_set(Elm_Win *obj, const int *rotations, unsigned int count) +{ + Eina_Bool allow[4] = { 0, }; + int found = 0; + + if (!rotations || !count) goto end; + for (unsigned k = 0; (k < count) && (found < 4); k++) + { + int rot = (((rotations[k] % 360) + 360) % 360) / 90; + if (!allow[rot]) + { + allow[rot] = EINA_TRUE; + found++; + } + } + +end: + efl_ui_win_wm_available_rotations_set(obj, allow[0], allow[1], allow[2], allow[3]); +} + +EAPI Eina_Bool +elm_win_wm_rotation_available_rotations_get(const Elm_Win *obj, int **rotations, unsigned int *count) +{ + int rots[4] = { 0, }; + Eina_Bool allow[4] = { 0, }; + unsigned cnt = 0; + + if (!efl_ui_win_wm_available_rotations_get(obj, &allow[0], &allow[1], &allow[2], &allow[3])) + goto none; + + for (int k = 0; k < 4; k++) + if (allow[k]) + rots[cnt++] = k * 90; + + if (!cnt) goto none; + + if (rotations) + { + *rotations = malloc(sizeof(int) * cnt); + if (!*rotations) goto none; + memcpy(*rotations, rots, cnt * sizeof(int)); + } + if (count) *count = cnt; return EINA_TRUE; + +none: + if (rotations) *rotations = NULL; + if (count) *count = 0; + return EINA_FALSE; } EOLIAN static void diff --git a/src/lib/elementary/efl_ui_win.eo b/src/lib/elementary/efl_ui_win.eo index c0925fb685..66a3d47223 100644 --- a/src/lib/elementary/efl_ui_win.eo +++ b/src/lib/elementary/efl_ui_win.eo @@ -218,35 +218,24 @@ class Efl.Ui.Win (Elm.Widget, Efl.Canvas, Efl.Access.Window, } } @property wm_available_rotations { + [[Defines which rotations this window supports. + + The window manager will refer to these hints and rotate the window + accordingly, depending on the device orientation, for instance. + ]] + values { + allow_0: bool; [[Normal orientation.]] + allow_90: bool; [[Rotated 90 degrees CCW.]] + allow_180: bool; [[Rotated 180 degrees.]] + allow_270: bool; [[Rotated 270 degrees CCW (i.e. 90 CW).]] + } set { - [[Set the array of available window rotations. - - This function is used to set the available rotations to give - the hints to WM. WM will refer this hints and set the - orientation window properly. - - @since 1.9 - ]] - legacy: elm_win_wm_rotation_available_rotations_set; - values { - /* FIXME: array */ - rotations: ptr(const(int)); [[The array of rotation value.]] - count: uint; [[The size of the rotations array.]] - } + legacy: null; } get { - [[Get the array of available window rotations. - - This function is used to get the available rotations. - - @since 1.9 - ]] - legacy: elm_win_wm_rotation_available_rotations_get; - values { - rotations: ptr(int); [[The array of rotation value.]] - count: uint; [[The size of the rotations array.]] - } - return: bool; [[$true on success, $false otherwise]] + legacy: null; + return: bool; [[Returns $false if available rotations were + not specified.]] } } @property wm_available_profiles { diff --git a/src/lib/elementary/elm_win_legacy.h b/src/lib/elementary/elm_win_legacy.h index 74774c7d19..0acba9db7d 100644 --- a/src/lib/elementary/elm_win_legacy.h +++ b/src/lib/elementary/elm_win_legacy.h @@ -1289,3 +1289,36 @@ EAPI void elm_win_available_profiles_set(Elm_Win *obj, const char **profiles, un * @ingroup Efl_Ui_Win */ EAPI Eina_Bool elm_win_available_profiles_get(const Elm_Win *obj, char ***profiles, unsigned int *count); + +/** + * @brief Set the array of available window rotations. + * + * This function is used to set the available rotations to give the hints to + * WM. WM will refer this hints and set the orientation window properly. + * + * @param[in] obj The object. + * @param[in] rotations The array of rotation value. + * @param[in] count The size of the rotations array. + * + * @since 1.9 + * + * @ingroup Efl_Ui_Win + */ +EAPI void elm_win_wm_rotation_available_rotations_set(Elm_Win *obj, const int *rotations, unsigned int count); + +/** + * @brief Get the array of available window rotations. + * + * This function is used to get the available rotations. + * + * @param[in] obj The object. + * @param[out] rotations The array of rotation value. + * @param[out] count The size of the rotations array. + * + * @return @c true on success, @c false otherwise + * + * @since 1.9 + * + * @ingroup Efl_Ui_Win + */ +EAPI Eina_Bool elm_win_wm_rotation_available_rotations_get(const Elm_Win *obj, int **rotations, unsigned int *count);