|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "ecore_evas_wayland_private.h"
|
|
|
|
#include <Evas_Engine_Wayland.h>
|
|
|
|
#include "ecore_wl2_internal.h"
|
|
|
|
|
|
|
|
EAPI extern Eina_List *_evas_canvas_image_data_unset(Evas *eo_e);
|
|
|
|
EAPI extern void _evas_canvas_image_data_regenerate(Eina_List *list);
|
|
|
|
|
|
|
|
#define _smart_frame_type "ecore_evas_wl_frame"
|
|
|
|
|
|
|
|
static const char *interface_wl_name = "wayland";
|
|
|
|
static const int interface_wl_version = 1;
|
|
|
|
|
|
|
|
Eina_List *ee_list;
|
|
|
|
|
|
|
|
/* local structure for evas devices with IDs */
|
|
|
|
typedef struct _EE_Wl_Device EE_Wl_Device;
|
|
|
|
struct _EE_Wl_Device
|
|
|
|
{
|
|
|
|
Evas_Device *seat;
|
|
|
|
Evas_Device *pointer;
|
|
|
|
Evas_Device *keyboard;
|
|
|
|
Evas_Device *touch;
|
|
|
|
unsigned int id;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* local variables */
|
|
|
|
static int _ecore_evas_wl_init_count = 0;
|
|
|
|
static Eina_Array *_ecore_evas_wl_event_hdls;
|
|
|
|
|
|
|
|
static void _ecore_evas_wayland_resize(Ecore_Evas *ee, int location);
|
|
|
|
static void _ecore_evas_wl_common_rotation_set(Ecore_Evas *ee, int rotation, int resize);
|
|
|
|
static void _ecore_evas_wl_selection_init(Ecore_Evas *ee);
|
|
|
|
|
|
|
|
/* local functions */
|
|
|
|
static void
|
|
|
|
_anim_cb_tick(Ecore_Wl2_Window *win EINA_UNUSED, uint32_t timestamp, void *data)
|
|
|
|
{
|
|
|
|
Ecore_Evas *ee = data;
|
|
|
|
Ecore_Evas_Engine_Wl_Data *edata;
|
|
|
|
double t;//, rt;
|
|
|
|
/* static double pt = 0.0, prt = 0.0; */
|
|
|
|
|
|
|
|
edata = ee->engine.data;
|
|
|
|
|
|
|
|
if (!edata->ticking) return;
|
|
|
|
t = ((double)timestamp / 1000.0);
|
|
|
|
ecore_loop_time_set(t);
|
|
|
|
/* rt = ecore_time_get(); */
|
|
|
|
/* printf("ECORE_EVAS: wl client anim tick %p | %p - %1.5f @ %1.5f delt=%1.5f | %1.5f\n", ee, edata, t, ecore_time_get(), t - pt, rt - prt); */
|
|
|
|
ecore_evas_animator_tick(ee, NULL, t);
|
|
|
|
/* pt = t; */
|
|
|
|
/* prt = rt; */
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_evas_wl_common_animator_register(Ecore_Evas *ee)
|
|
|
|
{
|
|
|
|
Ecore_Evas_Engine_Wl_Data *edata;
|
|
|
|
|
|
|
|
edata = (Ecore_Evas_Engine_Wl_Data *)ee->engine.data;
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN(edata->ticking);
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN(edata->frame != NULL);
|
|
|
|
|
|
|
|
edata->frame =
|
|
|
|
ecore_wl2_window_frame_callback_add(edata->win, _anim_cb_tick, ee);
|
|
|
|
if (!ecore_wl2_window_pending_get(edata->win) && !ee->in_async_render &&
|
|
|
|
!ee->animator_ticked && !ee->animator_ran && !ee->draw_block)
|
|
|
|
ecore_wl2_window_false_commit(edata->win);
|
|
|
|
edata->ticking = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_evas_wl_common_animator_unregister(Ecore_Evas *ee)
|
|
|
|
{
|
|
|
|
Ecore_Evas_Engine_Wl_Data *edata;
|
|
|
|
|
|
|
|
edata = ee->engine.data;
|
|
|
|
edata->ticking = EINA_FALSE;
|
|
|
|
if (edata->frame)
|
|
|
|
ecore_wl2_window_frame_callback_del(edata->frame);
|
|
|
|
edata->frame = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_evas_wl_common_evas_changed(Ecore_Evas *ee, Eina_Bool changed)
|
|
|
|
{
|
|
|
|
Ecore_Evas_Engine_Wl_Data *edata;
|
|
|
|
|
|
|
|
if (changed) return;
|
|
|
|
|
|
|
|
edata = (Ecore_Evas_Engine_Wl_Data *)ee->engine.data;
|
|
|
|
if (edata->ticking && !ecore_wl2_window_pending_get(edata->win))
|
|
|
|
ecore_wl2_window_false_commit(edata->win);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_evas_wl_common_state_update(Ecore_Evas *ee)
|
|
|
|
{
|
|
|
|
if (ee->func.fn_state_change) ee->func.fn_state_change(ee);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_evas_wl_common_wm_rotation_protocol_set(Ecore_Evas *ee)
|
|
|
|
{
|
|
|
|
Ecore_Evas_Engine_Wl_Data *wdata;
|
|
|
|
|
|
|
|
wdata = ee->engine.data;
|
|
|
|
|
|
|
|
ee->prop.wm_rot.supported =
|
|
|
|
ecore_wl2_window_wm_rotation_supported_get(wdata->win);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_ecore_evas_wl_common_cb_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Ecore_Evas *ee;
|
|
|
|
Ecore_Event_Mouse_IO *ev;
|
|
|
|
|
|
|
|
LOGFN;
|
|
|
|
|
|
|
|
ev = event;
|
|
|
|
ee = ecore_event_window_match((Ecore_Window)ev->window);
|
|
|
|
if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
|
|
|
|
if ((Ecore_Window)ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
|
|
|
|
if (_ecore_evas_mouse_in_check(ee, ev->dev)) return ECORE_CALLBACK_PASS_ON;
|
|
|
|
|
|
|
|
_ecore_evas_mouse_inout_set(ee, ev->dev, EINA_TRUE, EINA_FALSE);
|
|
|
|
ecore_event_evas_seat_modifier_lock_update(ee->evas, ev->modifiers, ev->dev);
|
|
|
|
evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL);
|
|
|
|
_ecore_evas_mouse_device_move_process(ee, ev->dev, ev->x, ev->y, ev->timestamp);
|
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_ecore_evas_wl_common_cb_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Ecore_Evas *ee;
|
|
|
|
Ecore_Event_Mouse_IO *ev;
|
|
|
|
|
|
|
|
LOGFN;
|
|
|
|
|
|
|
|
ev = event;
|
|
|
|
ee = ecore_event_window_match((Ecore_Window)ev->window);
|
|
|
|
if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
|
|
|
|
if ((Ecore_Window)ev->window != ee->prop.window)
|
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
if (!_ecore_evas_mouse_in_check(ee, ev->dev)) return ECORE_CALLBACK_PASS_ON;
|
|
|
|
|
|
|
|
ecore_event_evas_seat_modifier_lock_update(ee->evas,
|
|
|
|
ev->modifiers, ev->dev);
|
|
|
|
_ecore_evas_mouse_device_move_process(ee, ev->dev, ev->x, ev->y, ev->timestamp);
|
|
|
|
evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL);
|
|
|
|
_ecore_evas_mouse_inout_set(ee, ev->dev, EINA_FALSE, EINA_FALSE);
|
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_ecore_evas_wl_common_cb_focus_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Ecore_Evas *ee;
|
|
|
|
Ecore_Wl2_Event_Focus_In *ev;
|
|
|
|
|
|
|
|
LOGFN;
|
|
|
|
|
|
|
|
ev = event;
|
|
|
|
ee = ecore_event_window_match((Ecore_Window)ev->window);
|
|
|
|
if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
|
|
|
|
if ((Ecore_Window)ev->window != ee->prop.window)
|
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
_ecore_evas_focus_device_set(ee, ev->dev, EINA_TRUE);
|
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_ecore_evas_wl_common_cb_focus_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Ecore_Evas *ee;
|
|
|
|
Ecore_Wl2_Event_Focus_Out *ev;
|
|
|
|
|
|
|
|
LOGFN;
|
|
|
|
|
|
|
|
ev = event;
|
|
|
|
ee = ecore_event_window_match((Ecore_Window)ev->window);
|
|
|
|
if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
|
|
|
|
if ((Ecore_Window)ev->window != ee->prop.window)
|
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
_ecore_evas_focus_device_set(ee, ev->dev, EINA_FALSE);
|
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ee_display_unset(Ecore_Evas *ee)
|
|
|
|
{
|
|
|
|
Evas_Engine_Info_Wayland *einfo;
|
|
|
|
Ecore_Evas_Engine_Wl_Data *wdata;
|
|
|
|
|
|
|
|
einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
|
|
|
|
if (!einfo) return;
|
|
|
|
|
|
|
|
wdata = ee->engine.data;
|
|
|
|
if (!strcmp(ee->driver, "wayland_egl"))
|
|
|
|
wdata->regen_objs = _evas_canvas_image_data_unset(ecore_evas_get(ee));
|
|
|
|
|
|
|
|
if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
|
|
|
|
WRN("Failed to set Evas Engine Info for '%s'", ee->driver);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_ecore_evas_wl_common_cb_disconnect(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Ecore_Wl2_Event_Disconnect *ev = event;
|
|
|
|
Eina_List *l;
|
|
|
|
Ecore_Evas *ee;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(ee_list, l, ee)
|
|
|
|
{
|
|
|
|
Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
|
|
|
|
|
|
|
|
if (wdata->display != ev->display) continue;
|
|
|
|
wdata->sync_done = EINA_FALSE;
|
|
|
|
wdata->defer_show = EINA_TRUE;
|
|
|
|
ee->visible = EINA_FALSE;
|
|
|
|
wdata->reset_pending = 1;
|
|
|
|
ee->draw_block = EINA_TRUE;
|
|
|
|
_ee_display_unset(ee);
|
|
|
|
}
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
ee_needs_alpha(Ecore_Evas *ee)
|
|
|
|
{
|
|
|
|
return ee->shadow.l || ee->shadow.r || ee->shadow.t || ee->shadow.b ||
|
|
|
|
ee->alpha;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_evas_wayland_window_update(Ecore_Evas *ee, Ecore_Evas_Engine_Wl_Data *wdata, Eina_Bool new_alpha)
|
|
|
|
{
|
|
|
|
Evas_Engine_Info_Wayland *einfo;
|
|
|
|
Eina_Bool has_shadow, needs_alpha, change;
|
|
|
|
int w, h, fw, fh, shw = 0, shh = 0;
|
|
|
|
int fullw, fullh;
|
|
|
|
|
|
|
|
einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(einfo);
|
|
|
|
|
|
|
|
change = ee->shadow.changed || (new_alpha != ee->alpha);
|
|
|
|
ee->alpha = new_alpha;
|
|
|
|
has_shadow = ee->shadow.l || ee->shadow.r || ee->shadow.t || ee->shadow.b;
|
|
|
|
|
|
|
|
needs_alpha = ee_needs_alpha(ee);
|
|
|
|
|
|
|
|
if (einfo->info.destination_alpha != needs_alpha)
|
|
|
|
{
|
|
|
|
ecore_wl2_window_alpha_set(wdata->win, needs_alpha);
|
|
|
|
einfo->info.destination_alpha = needs_alpha;
|
|
|
|
if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
|
|
|
|
ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
|
|
|
|
|
|
|
|
change |= EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
|
|
|
|
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
|
|
|
|
|
|
|
|
if (has_shadow)
|
|
|
|
{
|
|
|
|
shh = ee->shadow.r + ee->shadow.l;
|
|
|
|
shw = ee->shadow.t + ee->shadow.b;
|
|
|
|
}
|
|
|
|
|
|
|
|
fullw = w + fw - shw;
|
|
|
|
fullh = h + fh - shh;
|
|
|
|
|
|
|
|
/* shadow but no window alpha means we have a translucent visual but the
|
|
|
|
* window contents are always opaque - we can set the opaque region
|
|
|
|
* hint so the compositor can render more efficiently
|
|
|
|
*/
|
|
|
|
if (has_shadow && !ee->alpha)
|
|
|
|
{
|
|
|
|
ecore_wl2_window_opaque_region_set(wdata->win,
|
|
|
|
ee->shadow.l, ee->shadow.t,
|
|
|
|
fullw, fullh);
|
|
|
|
}
|
|
|
|
/* No alpha, no shadows - this should really not be a visual capable
|
|
|
|
* of translucent behaviour, but just in case things are sketchy in
|
|
|
|
* the back-end, let the compositor know we're fully opaque.
|
|
|
|
*/
|
|
|
|
else if (!ee->alpha)
|
|
|
|
{
|
|
|
|
ecore_wl2_window_opaque_region_set(wdata->win, 0, 0, fullw, fullh);
|
|
|
|
}
|
|
|
|
/* alpha is set and we might use it, so we'd better clear the
|
|
|
|
* opaque region, let the compositor blend it all.
|
|
|
|
*/
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ecore_wl2_window_opaque_region_set(wdata->win, 0, 0, 0, 0);
|
|
|
|
}
|
|
|
|
ecore_wl2_window_input_region_set(wdata->win,
|
|
|
|
ee->shadow.l, ee->shadow.t,
|
|
|
|
fullw, fullh);
|
|
|
|
ecore_wl2_window_geometry_set(wdata->win,
|
|
|
|
ee->shadow.l, ee->shadow.t,
|
|
|
|
fullw, fullh);
|
|
|
|
if (!change) return;
|
|
|
|
|
|
|
|
if (ECORE_EVAS_PORTRAIT(ee))
|
|
|
|
evas_damage_rectangle_add(ee->evas, 0, 0, fullw, fullh);
|
|
|
|
else
|
|
|
|
evas_damage_rectangle_add(ee->evas, 0, 0, fullh, fullw);
|
|
|
|
|
|
|
|
ee->shadow.changed = EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_evas_wl_common_resize(Ecore_Evas *ee, int w, int h)
|
|
|
|
{
|
|
|
|
Ecore_Evas_Engine_Wl_Data *wdata;
|
|
|
|
int ow, oh, ew, eh, fw, fh;
|
|
|
|
int diff = 0;
|
|
|
|
|
|
|
|
LOGFN;
|
|
|
|
|
|
|
|
if (!ee) return;
|
|
|
|
|
|
|
|
wdata = ee->engine.data;
|
|
|
|
if (!wdata) return;
|
|
|
|
|
|
|
|
ee->req.w = w;
|
|
|
|
ee->req.h = h;
|
|
|
|
|
|
|
|
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
|
|
|
|
|
|
|
|
/* TODO: wayland client can resize the ecore_evas directly.
|
|
|
|
* In the future, we will remove ee->req value in wayland backend */
|
|
|
|
ew = ee->w;
|
|
|
|
eh = ee->h;
|
|
|
|
ee->w = w;
|
|
|
|
ee->h = h;
|
|
|
|
|
|
|
|
if (wdata->win->xdg_set_min_size && wdata->win->xdg_toplevel &&
|
|
|
|
wdata->win->pending.min)
|
|
|
|
{
|
|
|
|
wdata->win->xdg_set_min_size(wdata->win->xdg_toplevel,
|
|
|
|
ee->prop.min.w + fw, ee->prop.min.h + fh);
|
|
|
|
wdata->win->pending.min = 0;
|
|
|
|
}
|
|
|
|
if (wdata->win->xdg_set_max_size && wdata->win->xdg_toplevel &&
|
|
|
|
wdata->win->pending.max)
|
|
|
|
{
|
|
|
|
wdata->win->xdg_set_max_size(wdata->win->xdg_toplevel,
|
|
|
|
ee->prop.max.w + fw, ee->prop.max.h + fh);
|
|
|
|
wdata->win->pending.max = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (wdata->win->zxdg_set_min_size && wdata->win->zxdg_toplevel &&
|
|
|
|
wdata->win->pending.min)
|
|
|
|
{
|
|
|
|
wdata->win->zxdg_set_min_size(wdata->win->zxdg_toplevel,
|
|
|
|
ee->prop.min.w + fw, ee->prop.min.h + fh);
|
|
|
|
wdata->win->pending.min = 0;
|
|
|
|
}
|
|
|
|
if (wdata->win->zxdg_set_max_size && wdata->win->zxdg_toplevel &&
|
|
|
|
wdata->win->pending.max)
|
|
|
|
{
|
|
|
|
wdata->win->zxdg_set_max_size(wdata->win->zxdg_toplevel,
|
|
|
|
ee->prop.max.w + fw, ee->prop.max.h + fh);
|
|
|
|
wdata->win->pending.max = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ee->prop.fullscreen)
|
|
|
|
{
|
|
|
|
int maxw = 0, maxh = 0;
|
|
|
|
int minw = 0, minh = 0;
|
|
|
|
|
|
|
|
if (ee->prop.min.w > 0) minw = (ee->prop.min.w);
|
|
|
|
if (ee->prop.min.h > 0) minh = (ee->prop.min.h);
|
|
|
|
if (ee->prop.max.w > 0) maxw = (ee->prop.max.w);
|
|
|
|
if (ee->prop.max.h > 0) maxh = (ee->prop.max.h);
|
|
|
|
|
|
|
|
if ((maxw > 0) && (w > maxw)) w = maxw;
|
|
|
|
else if (w < minw) w = minw;
|
|
|
|
|
|
|
|
if ((maxh > 0) && (h > maxh)) h = maxh;
|
|
|
|
else if (h < minh) h = minh;
|
|
|
|
|
|
|
|
if (!ee->prop.maximized)
|
|
|
|
{
|
|
|
|
/* calc new size using base size & step size */
|
|
|
|
if (ee->prop.step.w > 1)
|
|
|
|
{
|
|
|
|
int bw = ee->prop.base.w;
|
|
|
|
w = (bw + (((w - bw) / ee->prop.step.w) * ee->prop.step.w));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ee->prop.step.h > 1)
|
|
|
|
{
|
|
|
|
int bh = ee->prop.base.h;
|
|
|
|
h = (bh + (((h - bh) / ee->prop.step.h) * ee->prop.step.h));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!wdata->win->display->wl.efl_hints &&
|
|
|
|
EINA_DBL_NONZERO(ee->prop.aspect))
|
|
|
|
{
|
|
|
|
/* copied from e_client.c */
|
|
|
|
Evas_Aspect_Control aspect;
|
|
|
|
int aw, ah;
|
|
|
|
double val, a;
|
|
|
|
|
|
|
|
if (h > 0)
|
|
|
|
{
|
|
|
|
a = (double)w / (double)h;
|
|
|
|
if (fabs(a - ee->prop.aspect) > 0.001)
|
|
|
|
{
|
|
|
|
int step_w = ee->prop.step.w ?: 1;
|
|
|
|
int step_h = ee->prop.step.h ?: 1;
|
|
|
|
|
|
|
|
if (wdata->resizing ||
|
|
|
|
ecore_wl2_window_resizing_get(wdata->win))
|
|
|
|
ew = wdata->cw, eh = wdata->ch;
|
|
|
|
if (abs(w - ew) > abs(h - eh))
|
|
|
|
aspect = EVAS_ASPECT_CONTROL_HORIZONTAL;
|
|
|
|
else
|
|
|
|
aspect = EVAS_ASPECT_CONTROL_VERTICAL;
|
|
|
|
switch (aspect)
|
|
|
|
{
|
|
|
|
case EVAS_ASPECT_CONTROL_HORIZONTAL:
|
|
|
|
val = ((h - (w / ee->prop.aspect)) *
|
|
|
|
step_h) / step_h;
|
|
|
|
if (val > 0) ah = ceil(val);
|
|
|
|
else ah = floor(val);
|
|
|
|
if ((h - ah > minh) || (minh < 1))
|
|
|
|
{
|
|
|
|
h -= ah;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
EINA_FALLTHROUGH;
|
|
|
|
/* no break */
|
|
|
|
default:
|
|
|
|
val = (((h * ee->prop.aspect) - w) *
|
|
|
|
step_w) / step_w;
|
|
|
|
if (val > 0) aw = ceil(val);
|
|
|
|
else aw = floor(val);
|
|
|
|
if ((w + aw < maxw) || (maxw < 1))
|
|
|
|
w += aw;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ee->w = w;
|
|
|
|
ee->h = h;
|
|
|
|
ee->req.w = w;
|
|
|
|
ee->req.h = h;
|
|
|
|
|
|
|
|
if (ECORE_EVAS_PORTRAIT(ee))
|
|
|
|
{
|
|
|
|
w += fw;
|
|
|
|
h += fh;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
w += fh;
|
|
|
|
h += fw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ECORE_EVAS_PORTRAIT(ee))
|
|
|
|
evas_output_size_get(ee->evas, &ow, &oh);
|
|
|
|
else
|
|
|
|
evas_output_size_get(ee->evas, &oh, &ow);
|
|
|
|
|
|
|
|
if (ECORE_EVAS_PORTRAIT(ee) && ((ow != w) || (oh != h)))
|
|
|
|
diff = 1;
|
|
|
|
if (!ECORE_EVAS_PORTRAIT(ee) && ((ow != h) || (oh != w)))
|
|
|
|
diff = 1;
|
|
|
|
|
|
|
|
if (diff)
|
|
|
|
{
|
|
|
|
if (ECORE_EVAS_PORTRAIT(ee))
|
|
|
|
{
|
|
|
|
evas_output_size_set(ee->evas, w, h);
|
|
|
|
evas_output_viewport_set(ee->evas, 0, 0, w, h);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
evas_output_size_set(ee->evas, h, w);
|
|
|
|
evas_output_viewport_set(ee->evas, 0, 0, h, w);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ee->prop.avoid_damage)
|
|
|
|
{
|
|
|
|
int pdam = 0;
|
|
|
|
|
|
|
|
pdam = ecore_evas_avoid_damage_get(ee);
|
|
|
|
ecore_evas_avoid_damage_set(ee, 0);
|
|
|
|
ecore_evas_avoid_damage_set(ee, pdam);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ee->func.fn_resize) ee->func.fn_resize(ee);
|
|
|
|
}
|
|
|
|
_ecore_evas_wayland_window_update(ee, wdata, ee->alpha);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_evas_wl_common_wm_rot_manual_rotation_done_job(void *data)
|
|
|
|
{
|
|
|
|
Ecore_Evas *ee = (Ecore_Evas *)data;
|
|
|
|
Ecore_Evas_Engine_Wl_Data *wdata;
|
|
|
|
|
|
|
|
wdata = ee->engine.data;
|
|
|
|
|
|
|
|
wdata->wm_rot.manual_mode_job = NULL;
|
|
|
|
ee->prop.wm_rot.manual_mode.wait_for_done = EINA_FALSE;
|
|
|
|
|
|
|
|
ecore_wl2_window_rotation_change_done_send
|
|
|
|
(wdata->win, ee->rotation, ee->w, ee->h);
|
|
|
|
|
|
|
|
wdata->wm_rot.done = EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_evas_wl_common_wm_rot_manual_rotation_done(Ecore_Evas *ee)
|
|
|
|
{
|
|
|
|
if ((ee->prop.wm_rot.supported) &&
|
|
|
|
(ee->prop.wm_rot.app_set) &&
|
|
|
|
(ee->prop.wm_rot.manual_mode.set))
|
|
|
|
{
|
|
|
|
if (ee->prop.wm_rot.manual_mode.wait_for_done)
|
|
|
|
{
|
|
|
|
Ecore_Evas_Engine_Wl_Data *wdata;
|
|
|
|
|
|
|
|
wdata = ee->engine.data;
|
|
|
|
|
|
|
|
if (ee->prop.wm_rot.manual_mode.timer)
|
|
|
|
ecore_timer_del(ee->prop.wm_rot.manual_mode.timer);
|
|
|
|
ee->prop.wm_rot.manual_mode.timer = NULL;
|
|
|
|
|
|
|
|
if (wdata->wm_rot.manual_mode_job)
|
|
|
|
ecore_job_del(wdata->wm_rot.manual_mode_job);
|
|
|
|
|
|
|
|
wdata->wm_rot.manual_mode_job = ecore_job_add
|
|
|
|
(_ecore_evas_wl_common_wm_rot_manual_rotation_done_job, ee);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_ecore_evas_wl_common_wm_rot_manual_rotation_done_timeout(void *data)
|
|
|
|
{
|
|
|
|
Ecore_Evas *ee = data;
|
|
|
|
|
|
|
|
ee->prop.wm_rot.manual_mode.timer = NULL;
|
|
|
|
_ecore_evas_wl_common_wm_rot_manual_rotation_done(ee);
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_evas_wl_common_wm_rot_manual_rotation_done_timeout_update(Ecore_Evas *ee)
|
|
|
|
{
|
|
|
|
if (ee->prop.wm_rot.manual_mode.timer)
|
|
|
|
ecore_timer_del(ee->prop.wm_rot.manual_mode.timer);
|
|
|
|
|
|
|
|
ee->prop.wm_rot.manual_mode.timer = ecore_timer_add
|
|
|
|
(4.0f, _ecore_evas_wl_common_wm_rot_manual_rotation_done_timeout, ee);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_ecore_evas_wl_common_cb_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Ecore_Evas *ee;
|
|
|
|
Ecore_Evas_Engine_Wl_Data *wdata;
|
|
|
|
Ecore_Wl2_Event_Window_Configure *ev;
|
|
|
|
int nw = 0, nh = 0, fw, fh, pfw, pfh, sw, sh, contentw, contenth;
|
|
|
|
int ww, wh;
|
|
|
|
int framew, frameh;
|
|
|
|
Eina_Bool active, prev_max, prev_full, state_change = EINA_FALSE;
|
|
|
|
|
|
|
|
LOGFN;
|
|
|
|
|
|
|
|
ev = event;
|
|
|
|
ee = ecore_event_window_match((Ecore_Window)ev->win);
|
|
|
|
if (!ee) return ECORE_CALLBACK_PASS_ON;
|
|
|
|
if ((Ecore_Window)ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
|
|
|
|
|
|
|
|
wdata = ee->engine.data;
|
|
|
|
if (!wdata) return ECORE_CALLBACK_PASS_ON;
|
|
|
|
|
|
|
|
if (!ecore_wl2_window_resizing_get(wdata->win) && !wdata->resizing)
|
|
|
|
wdata->cw = wdata->ch = 0;
|
|
|
|
|
|
|
|
prev_max = ee->prop.maximized;
|
|
|
|
prev_full = ee->prop.fullscreen;
|
|
|
|
ee->prop.maximized =
|
|
|
|
(ev->states & ECORE_WL2_WINDOW_STATE_MAXIMIZED) ==
|
|
|
|
ECORE_WL2_WINDOW_STATE_MAXIMIZED;
|
|
|
|
ee->prop.fullscreen =
|
|
|
|
(ev->states & ECORE_WL2_WINDOW_STATE_FULLSCREEN) ==
|
|
|
|
ECORE_WL2_WINDOW_STATE_FULLSCREEN;
|
|
|
|
active = wdata->activated;
|
|
|
|
wdata->activated = ecore_wl2_window_activated_get(wdata->win);
|
|
|
|
|
|
|
|
/* If the compositor set these, we need to update internal state
|
|
|
|
* so things like CSD continue to function */
|
|
|
|
wdata->win->set_config.maximized = ee->prop.maximized;
|
|
|
|
wdata->win->set_config.fullscreen = ee->prop.fullscreen;
|
|
|
|
|
|
|
|
nw = ev->w;
|
|
|
|
nh = ev->h;
|
|
|
|
|
|
|
|
ecore_evas_geometry_get(ee, NULL, NULL, &ww, &wh);
|
|
|
|
|
|
|
|
sw = ee->shadow.l + ee->shadow.r;
|
|
|
|
sh = ee->shadow.t + ee->shadow.b;
|
|
|
|
evas_output_framespace_get(ee->evas, NULL, NULL, &framew, &frameh);
|
|
|
|
contentw = ww - (framew - sw);
|
|
|
|
contenth = wh - (frameh - sh);
|
|
|
|
pfw = fw = ww - contentw;
|
|
|
|
pfh = fh = wh - contenth;
|
|
|
|
|
|
|
|
if ((prev_max != ee->prop.maximized) ||
|
|
|
|
(prev_full != ee->prop.fullscreen) ||
|
|
|
|
(active != wdata->activated))
|
|
|
|
{
|
|
|
|
state_change = EINA_TRUE;
|
|
|
|
_ecore_evas_wl_common_state_update(ee);
|
|
|
|
sw = ee->shadow.l + ee->shadow.r;
|
|
|
|
sh = ee->shadow.t + ee->shadow.b;
|
|
|
|
evas_output_framespace_get(ee->evas, NULL, NULL, &framew, &frameh);
|
|