|
|
|
#define E_COMP_WL
|
|
|
|
#include "e.h"
|
|
|
|
|
|
|
|
/* handle include for printing uint64_t */
|
|
|
|
#define __STDC_FORMAT_MACROS
|
|
|
|
#include <inttypes.h>
|
|
|
|
|
|
|
|
#define COMPOSITOR_VERSION 4
|
|
|
|
|
|
|
|
E_API int E_EVENT_WAYLAND_GLOBAL_ADD = -1;
|
|
|
|
|
|
|
|
#ifndef EGL_HEIGHT
|
|
|
|
# define EGL_HEIGHT 0x3056
|
|
|
|
#endif
|
|
|
|
#ifndef EGL_WIDTH
|
|
|
|
# define EGL_WIDTH 0x3057
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Resource Data Mapping: (wl_resource_get_user_data)
|
|
|
|
*
|
|
|
|
* wl_surface == e_pixmap
|
|
|
|
* wl_region == eina_tiler
|
|
|
|
* wl_subsurface == e_client
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void _e_comp_wl_subsurface_parent_commit(E_Client *ec, Eina_Bool parent_synchronized);
|
|
|
|
|
|
|
|
EINTERN Eina_Bool e_comp_wl_extensions_init(void);
|
|
|
|
|
|
|
|
/* local variables */
|
|
|
|
/* static Eina_Hash *clients_win_hash = NULL; */
|
|
|
|
static Eina_List *handlers = NULL;
|
|
|
|
static double _last_event_time = 0.0;
|
|
|
|
|
|
|
|
static int64_t surface_id = 0;
|
|
|
|
|
|
|
|
static Eina_List *grab_clients;
|
|
|
|
static Eina_List *grab_cbs;
|
|
|
|
|
|
|
|
/* local functions */
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_parent_client_contains_pointer(E_Client *ec)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
E_Client *c, *top = ec;
|
|
|
|
|
|
|
|
while (top->parent) top = top->parent;
|
|
|
|
|
|
|
|
if (top == ec) return EINA_FALSE;
|
|
|
|
|
|
|
|
if (top->mouse.in) return EINA_TRUE;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(top->comp_data->sub.list, l, c)
|
|
|
|
if (c->mouse.in) return EINA_TRUE;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(top->transients, l, c)
|
|
|
|
if ((ec != c) && c->mouse.in) return EINA_TRUE;
|
|
|
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct wl_resource *
|
|
|
|
_output_resource_find(Eina_List *reslist, struct wl_resource *surface)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
struct wl_client *client;
|
|
|
|
struct wl_resource *res;
|
|
|
|
|
|
|
|
client = wl_resource_get_client(surface);
|
|
|
|
EINA_LIST_FOREACH(reslist, l, res)
|
|
|
|
if (wl_resource_get_client(res) == client) return res;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_surface_outputs_update(E_Client *ec)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
E_Zone *zone;
|
|
|
|
int32_t obits = 0;
|
|
|
|
|
|
|
|
if (ec->visible)
|
|
|
|
EINA_LIST_FOREACH(e_comp->zones, l, zone)
|
|
|
|
if (E_INTERSECTS(zone->x, zone->y, zone->w, zone->h,
|
|
|
|
ec->x, ec->y, ec->w, ec->h)) obits |= 1 << zone->id;
|
|
|
|
|
|
|
|
if (obits != ec->comp_data->on_outputs)
|
|
|
|
{
|
|
|
|
int32_t leave = (obits ^ ec->comp_data->on_outputs) & ec->comp_data->on_outputs;
|
|
|
|
int32_t enter = (obits ^ ec->comp_data->on_outputs) & obits;
|
|
|
|
|
|
|
|
ec->comp_data->on_outputs = obits;
|
|
|
|
EINA_LIST_FOREACH(e_comp->zones, l, zone)
|
|
|
|
{
|
|
|
|
struct wl_resource *s, *res;
|
|
|
|
E_Comp_Wl_Output *wlo;
|
|
|
|
|
|
|
|
s = ec->comp_data->surface;
|
|
|
|
wlo = zone->output;
|
|
|
|
if (!wlo) continue;
|
|
|
|
|
|
|
|
res = _output_resource_find(wlo->resources, s);
|
|
|
|
if (!res) continue;
|
|
|
|
|
|
|
|
if (leave & (1 << zone->id)) wl_surface_send_leave(s, res);
|
|
|
|
if (enter & (1 << zone->id)) wl_surface_send_enter(s, res);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_configure_send(E_Client *ec, Eina_Bool edges)
|
|
|
|
{
|
|
|
|
int w = 0, h = 0;
|
|
|
|
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
if (ec->changes.size || e_pixmap_usable_get(ec->pixmap))
|
|
|
|
{
|
|
|
|
if (e_comp_object_frame_exists(ec->frame))
|
|
|
|
w = ec->client.w, h = ec->client.h;
|
|
|
|
else
|
|
|
|
w = ec->w, h = ec->h;
|
|
|
|
}
|
|
|
|
ec->comp_data->shell.configure_send(ec->comp_data->shell.surface,
|
|
|
|
edges * e_comp_wl->resize.edges,
|
|
|
|
w, h);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static void */
|
|
|
|
/* _e_comp_wl_log_cb_print(const char *format, va_list args) */
|
|
|
|
/* { */
|
|
|
|
/* EINA_LOG_DOM_INFO(e_log_dom, format, args); */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_modules_load(void)
|
|
|
|
{
|
|
|
|
const char **m, *mods[] =
|
|
|
|
{
|
|
|
|
#ifdef USE_MODULE_WL_DESKTOP_SHELL
|
|
|
|
"wl_desktop_shell",
|
|
|
|
#endif
|
|
|
|
#ifdef USE_MODULE_XWAYLAND
|
|
|
|
"xwayland",
|
|
|
|
#endif
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
for (m = mods; *m; m++)
|
|
|
|
{
|
|
|
|
E_Module *mod = e_module_find(*m);
|
|
|
|
|
|
|
|
if (!mod)
|
|
|
|
mod = e_module_new(*m);
|
|
|
|
|
|
|
|
if (mod)
|
|
|
|
e_module_enable(mod);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec = data;
|
|
|
|
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
|
|
|
|
if (!ec->override) e_hints_window_visible_set(ec);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_hide(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec = data;
|
|
|
|
|
|
|
|
if (!e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
if (!e_object_ref_get(E_OBJECT(ec))) return;
|
|
|
|
|
|
|
|
e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
|
|
|
|
e_comp_object_dirty(ec->frame);
|
|
|
|
if (e_comp_object_render(ec->frame))
|
|
|
|
e_comp_client_post_update_add(ec);
|
|
|
|
e_object_unref(E_OBJECT(ec));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_mouse_in(E_Client *ec, Evas_Event_Mouse_In *ev)
|
|
|
|
{
|
|
|
|
struct wl_resource *res;
|
|
|
|
struct wl_client *wc;
|
|
|
|
Eina_List *l;
|
|
|
|
uint32_t serial;
|
|
|
|
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
|
|
|
|
if (!ec->comp_data->surface) return;
|
|
|
|
|
|
|
|
e_comp_wl->ptr.ec = ec;
|
|
|
|
if (e_comp_wl->drag)
|
|
|
|
{
|
|
|
|
e_comp_wl_data_device_send_enter(ec);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!eina_list_count(e_comp_wl->ptr.resources)) return;
|
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
|
|
|
serial = wl_display_next_serial(e_comp_wl->wl.disp);
|
|
|
|
EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Pointer *ptr = wl_resource_get_user_data(res);
|
|
|
|
|
|
|
|
if (!e_comp_wl_input_pointer_check(res)) continue;
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
|
|
|
ptr->entered = 1;
|
|
|
|
wl_pointer_send_enter(res, serial, ec->comp_data->surface,
|
e_comp_wl: fix not sending a mouse enter event to client.
Summary:
First of all, currently cdata->ptr.x,y contains e_client related pos.
But, cdata is owned by e_comp, not per e_client. So cdata->ptr.x,y should contain
absolute pos.
And, when a pointer resource is created, enter event should be sent to client.
Change-Id: I21cb031e293fe281e35ba89f3a96116a28a48856
Signed-off-by: Boram Park <boram1288.park@samsung.com>
Test Plan:
1. run e as wayland server
2. move cursor to around 50,50
3. run elementary_test
4. click the mouse left button on slide toggle widget.
(Don't move a cursor out of elementary_test. If you do, you can't find bug)
Reviewers: gwanglim, raster, devilhorns, ManMower, zmike
Reviewed By: zmike
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D2330
8 years ago
|
|
|
wl_fixed_from_int(ev->canvas.x - ec->client.x),
|
|
|
|
wl_fixed_from_int(ev->canvas.y - ec->client.y));
|
|
|
|
e_comp_wl_input_pointer_cursor_update(ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
|
|
|
if (e_comp_object_frame_exists(obj)) return;
|
|
|
|
_e_comp_wl_mouse_in(data, event_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_cb_ssd_mouse_in(void *data, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
|
|
|
E_Client *ec = data;
|
|
|
|
|
|
|
|
if (!e_comp_object_frame_exists(obj)) return;
|
|
|
|
if (!e_object_is_del(data))
|
|
|
|
ec->comp_data->ssd_mouse_in = 1;
|
|
|
|
_e_comp_wl_mouse_in(data, event_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_mouse_out(E_Client *ec)
|
|
|
|
{
|
|
|
|
struct wl_resource *res;
|
|
|
|
struct wl_client *wc;
|
|
|
|
Eina_List *l;
|
|
|
|
uint32_t serial;
|
|
|
|
|
|
|
|
if ((ec == e_client_action_get()) && e_grabinput_mouse_win_get()) return;
|
|
|
|
/* FIXME? this is a hack to just reset the cursor whenever we mouse out. not sure if accurate */
|
|
|
|
{
|
|
|
|
e_pointer_object_set(e_comp->pointer, NULL, 0, 0);
|
|
|
|
evas_object_show(e_comp->pointer->o_ptr);
|
|
|
|
}
|
|
|
|
if (e_comp_wl->ptr.ec == ec)
|
|
|
|
e_comp_wl->ptr.ec = NULL;
|
|
|
|
if (!ec->comp_data) return;
|
|
|
|
|
|
|
|
if (!ec->comp_data->surface) return;
|
|
|
|
if (e_comp_wl->drag)
|
|
|
|
{
|
|
|
|
e_comp_wl_data_device_send_leave(ec);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!eina_list_count(e_comp_wl->ptr.resources)) return;
|
|
|
|
|
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
|
|
|
serial = wl_display_next_serial(e_comp_wl->wl.disp);
|
|
|
|
EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Pointer *ptr = wl_resource_get_user_data(res);
|
|
|
|
if (!e_comp_wl_input_pointer_check(res)) continue;
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
|
|
|
ptr->entered = 0;
|
|
|
|
wl_pointer_send_leave(res, serial, ec->comp_data->surface);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
|
|
{
|
|
|
|
if (e_comp_object_frame_exists(obj)) return;
|
|
|
|
_e_comp_wl_mouse_out(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_cb_ssd_mouse_out(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec = data;
|
|
|
|
|
|
|
|
if (!e_comp_object_frame_exists(obj)) return;
|
|
|
|
if (!e_object_is_del(data))
|
|
|
|
ec->comp_data->ssd_mouse_in = 0;
|
|
|
|
_e_comp_wl_mouse_out(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_send_mouse_move(E_Client *ec, int x, int y, unsigned int timestamp)
|
|
|
|
{
|
|
|
|
struct wl_resource *res;
|
|
|
|
struct wl_client *wc;
|
|
|
|
Eina_List *l;
|
|
|
|
E_Client *tec, *tec_in = NULL;
|
|
|
|
Eina_Bool found = EINA_FALSE;
|
|
|
|
Evas_Event_Mouse_In ev;
|
|
|
|
|
|
|
|
/* begin hacks:
|
|
|
|
*
|
|
|
|
* this should be handled by setting NOGRAB pointer mode on comp object internals,
|
|
|
|
* ie. 03a4ecbdb0972f8267c07ea14d752fcee69bd9fa
|
|
|
|
* but doing so breaks dnd eventing.
|
|
|
|
*
|
|
|
|
* instead, walk the transients list, assuming (correctly) that they are listed from
|
|
|
|
* bottom to top, and send mouse events to whichever surface the pointer is in
|
|
|
|
*/
|
|
|
|
ev.canvas.x = x;
|
|
|
|
ev.canvas.y = y;
|
|
|
|
EINA_LIST_FOREACH(ec->transients, l, tec)
|
|
|
|
{
|
|
|
|
if (e_client_util_ignored_get(tec) || (!evas_object_visible_get(tec->frame)))
|
|
|
|
continue;
|
|
|
|
if (tec->mouse.in) tec_in = tec;
|
|
|
|
if (E_INSIDE(x, y, tec->x, tec->y, tec->w, tec->h))
|
|
|
|
{
|
|
|
|
if (tec_in && (tec != tec_in))
|
|
|
|
{
|
|
|
|
e_client_mouse_out(tec_in, x, y);
|
|
|
|
_e_comp_wl_mouse_out(tec_in);
|
|
|
|
tec_in = NULL;
|
|
|
|
}
|
|
|
|
e_client_mouse_in(tec, x, y);
|
|
|
|
_e_comp_wl_mouse_in(tec, &ev);
|
|
|
|
e_client_mouse_move(tec, &(Evas_Point){x, y});
|
|
|
|
_e_comp_wl_send_mouse_move(tec, x, y, timestamp);
|
|
|
|
found = EINA_TRUE;
|
|
|
|
}
|
|
|
|
else if (tec->mouse.in)
|
|
|
|
{
|
|
|
|
e_client_mouse_out(tec, x, y);
|
|
|
|
_e_comp_wl_mouse_out(tec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (found) return;
|
|
|
|
/* if a transient previously had mouse.in, re-set mouse.in to the parent */
|
|
|
|
if (tec_in)
|
|
|
|
{
|
|
|
|
e_client_mouse_in(ec, x, y);
|
|
|
|
_e_comp_wl_mouse_in(ec, &ev);
|
|
|
|
e_client_mouse_move(ec, &(Evas_Point){x, y});
|
|
|
|
}
|
|
|
|
/* end hacks */
|
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
|
|
|
EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
|
|
|
|
{
|
|
|
|
if (!e_comp_wl_input_pointer_check(res)) continue;
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
|
|
|
wl_pointer_send_motion(res, timestamp,
|
|
|
|
wl_fixed_from_int(x - ec->client.x),
|
|
|
|
wl_fixed_from_int(y - ec->client.y));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_e_comp_wl_evas_cb_mouse_internal_check(E_Client *ec, int x, int y)
|
|
|
|
{
|
|
|
|
if (!e_comp_object_frame_exists(ec->frame)) return EINA_TRUE;
|
|
|
|
if (E_INSIDE(x, y, ec->client.x, ec->client.y, ec->client.w, ec->client.h)) return EINA_TRUE;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
E_Client *ec = data;
|
|
|
|
Evas_Event_Mouse_Move *ev = event;
|
|
|
|
|
|
|
|
if (ec == e_client_action_get()) return;
|
|
|
|
if (!ec->mouse.in) return;
|
|
|
|
if (!_e_comp_wl_evas_cb_mouse_internal_check(ec, ev->cur.canvas.x, ev->cur.canvas.y))
|
|
|
|
{
|
|
|
|
e_client_mouse_move(ec, &(Evas_Point){ev->cur.canvas.x, ev->cur.canvas.y});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
if (ec->ignored) return;
|
|
|
|
if (!ec->comp_data->surface) return;
|
|
|
|
|
|
|
|
if ((!e_comp_wl->drag_client) ||
|
|
|
|
(!e_client_has_xwindow(e_comp_wl->drag_client)) ||
|
|
|
|
e_comp_wl->drag_client->override)
|
|
|
|
_e_comp_wl_send_mouse_move(ec, ev->cur.canvas.x, ev->cur.canvas.y, ev->timestamp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
E_Client *ec = data;
|
|
|
|
Evas_Event_Mouse_Down *ev = event;
|
|
|
|
|
|
|
|
if (!_e_comp_wl_evas_cb_mouse_internal_check(ec, ev->output.x, ev->output.y)) return;
|
|
|
|
e_comp_wl_evas_handle_mouse_button(ec, ev->timestamp, ev->button,
|
|
|
|
WL_POINTER_BUTTON_STATE_PRESSED);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
E_Client *ec = data;
|
|
|
|
Evas_Event_Mouse_Up *ev = event;
|
|
|
|
|
|
|
|
if (!_e_comp_wl_evas_cb_mouse_internal_check(ec, ev->output.x, ev->output.y)) return;
|
|
|
|
e_comp_wl_evas_handle_mouse_button(ec, ev->timestamp, ev->button,
|
|
|
|
WL_POINTER_BUTTON_STATE_RELEASED);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_mouse_wheel(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
Evas_Event_Mouse_Wheel *ev;
|
|
|
|
struct wl_resource *res;
|
|
|
|
struct wl_client *wc;
|
|
|
|
Eina_List *l;
|
|
|
|
uint32_t axis, dir;
|
|
|
|
|
|
|
|
ev = event;
|
|
|
|
if (!(ec = data)) return;
|
|
|
|
if (ec == e_client_action_get()) return;
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
if (ec->ignored) return;
|
|
|
|
if (!ec->mouse.in) return;
|
|
|
|
|
|
|
|
if (ev->direction == 0)
|
|
|
|
axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
|
|
|
|
else
|
|
|
|
axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
|
|
|
|
|
|
|
|
if (ev->z < 0)
|
|
|
|
dir = -wl_fixed_from_int(abs(10 * ev->z));
|
|
|
|
else
|
|
|
|
dir = wl_fixed_from_int(10 * ev->z);
|
|
|
|
|
|
|
|
if (!ec->comp_data->surface) return;
|
|
|
|
|
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
|
|
|
EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
|
|
|
|
{
|
|
|
|
if (!e_comp_wl_input_pointer_check(res)) continue;
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
|
|
|
wl_pointer_send_axis(res, ev->timestamp, axis, dir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_multi_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
struct wl_client *wc;
|
|
|
|
uint32_t serial;
|
|
|
|
struct wl_resource *res;
|
|
|
|
E_Client *ec = data;
|
|
|
|
Evas_Event_Multi_Down *ev = event;
|
|
|
|
wl_fixed_t x, y;
|
|
|
|
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
if (!ec->comp_data->surface) return;
|
|
|
|
if (!ec->mouse.in) return;
|
|
|
|
|
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
|
|
|
serial = wl_display_next_serial(e_comp_wl->wl.disp);
|
|
|
|
|
|
|
|
x = wl_fixed_from_int(ev->canvas.x - ec->client.x);
|
|
|
|
y = wl_fixed_from_int(ev->canvas.y - ec->client.y);
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(e_comp_wl->touch.resources, l, res)
|
|
|
|
{
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
|
|
|
if (!e_comp_wl_input_touch_check(res)) continue;
|
|
|
|
wl_touch_send_down(res, serial, ev->timestamp,
|
|
|
|
ec->comp_data->surface, ev->device, x, y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_multi_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
struct wl_client *wc;
|
|
|
|
uint32_t serial;
|
|
|
|
struct wl_resource *res;
|
|
|
|
E_Client *ec = data;
|
|
|
|
Evas_Event_Multi_Up *ev = event;
|
|
|
|
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
if (!ec->comp_data->surface) return;
|
|
|
|
if (!ec->mouse.in) return;
|
|
|
|
|
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
|
|
|
serial = wl_display_next_serial(e_comp_wl->wl.disp);
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(e_comp_wl->touch.resources, l, res)
|
|
|
|
{
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
|
|
|
if (!e_comp_wl_input_touch_check(res)) continue;
|
|
|
|
wl_touch_send_up(res, serial, ev->timestamp, ev->device);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_multi_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
struct wl_client *wc;
|
|
|
|
struct wl_resource *res;
|
|
|
|
E_Client *ec = data;
|
|
|
|
Evas_Event_Multi_Move *ev = event;
|
|
|
|
wl_fixed_t x, y;
|
|
|
|
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
if (!ec->comp_data->surface) return;
|
|
|
|
if (!ec->mouse.in) return;
|
|
|
|
|
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
|
|
|
|
|
|
|
x = wl_fixed_from_int(ev->cur.canvas.x - ec->client.x);
|
|
|
|
y = wl_fixed_from_int(ev->cur.canvas.y - ec->client.y);
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(e_comp_wl->touch.resources, l, res)
|
|
|
|
{
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
|
|
|
if (!e_comp_wl_input_touch_check(res)) continue;
|
|
|
|
wl_touch_send_motion(res, ev->timestamp, ev->device, x, y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_client_priority_adjust(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_child, Eina_Bool do_child)
|
|
|
|
{
|
|
|
|
Eina_List *files;
|
|
|
|
char *file, buff[PATH_MAX];
|
|
|
|
FILE *f;
|
|
|
|
int pid2, ppid;
|
|
|
|
int num_read;
|
|
|
|
int n;
|
|
|
|
|
|
|
|
if (use_adj)
|
|
|
|
n = (getpriority(PRIO_PROCESS, pid) + adj);
|
|
|
|
else
|
|
|
|
n = set;
|
|
|
|
|
|
|
|
setpriority(PRIO_PROCESS, pid, n);
|
|
|
|
|
|
|
|
if (adj_child)
|
|
|
|
use_adj = EINA_TRUE;
|
|
|
|
|
|
|
|
if (!do_child) return;
|
|
|
|
|
|
|
|
files = ecore_file_ls("/proc");
|
|
|
|
EINA_LIST_FREE(files, file)
|
|
|
|
{
|
|
|
|
if (!isdigit(file[0]))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
snprintf(buff, sizeof(buff), "/proc/%s/stat", file);
|
|
|
|
if ((f = fopen(buff, "r")))
|
|
|
|
{
|
|
|
|
pid2 = -1;
|
|
|
|
ppid = -1;
|
|
|
|
num_read = fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid);
|
|
|
|
fclose(f);
|
|
|
|
if (num_read == 2 && ppid == pid)
|
|
|
|
_e_comp_wl_client_priority_adjust(pid2, set,
|
|
|
|
adj, use_adj,
|
|
|
|
adj_child, do_child);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_client_priority_raise(E_Client *ec)
|
|
|
|
{
|
|
|
|
if (ec->netwm.pid <= 0) return;
|
|
|
|
if (ec->netwm.pid == getpid()) return;
|
|
|
|
_e_comp_wl_client_priority_adjust(ec->netwm.pid,
|
|
|
|
e_config->priority - 1, -1,
|
|
|
|
EINA_FALSE, EINA_TRUE, EINA_FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_client_priority_normal(E_Client *ec)
|
|
|
|
{
|
|
|
|
if (ec->netwm.pid <= 0) return;
|
|
|
|
if (ec->netwm.pid == getpid()) return;
|
|
|
|
_e_comp_wl_client_priority_adjust(ec->netwm.pid, e_config->priority, 1,
|
|
|
|
EINA_FALSE, EINA_TRUE, EINA_FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_e_comp_wl_evas_cb_focus_in_timer(E_Client *ec)
|
|
|
|
{
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
|
|
|
|
|
|
|
|
ec->comp_data->on_focus_timer = NULL;
|
|
|
|
|
|
|
|
if (!e_comp_wl->kbd.focused) return EINA_FALSE;
|
|
|
|
e_comp_wl_input_keyboard_modifiers_update();
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_keyboard_resource_add(struct wl_resource *newres)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
struct wl_resource *res;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(e_comp_wl->kbd.focused, l, res)
|
|
|
|
if (res == newres) return EINA_FALSE;
|
|
|
|
|
|
|
|
e_comp_wl->kbd.focused = eina_list_append(e_comp_wl->kbd.focused, newres);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_focus_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|