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: ec464939d9 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
This commit is contained in:
Jean-Philippe Andre 2017-11-20 17:28:20 +09:00
parent dda18948ae
commit 372bf108a7
3 changed files with 131 additions and 52 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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);