Add focus surface setting of keyboard for copy and paste between clients

Summary:
To enable copy and paste between clients,
wayland data device requires to know what surface is focused.
So this revision have make keyboard get focused surface when client is focused or unfocused,
and create data_offer for new focused surface in order to let new focused surface be able to get data from current selection data_source.

Test Plan:
1. Run wayland server
2. Run elementary_test -to entry5 on wayland server.
3. Run elementary_test -to entry5 on wayland server again. (preparing two clients)
4. Copy text on one of clients, and paste to the other.

Reviewers: devilhorns

CC: gwanglim, cedric

Differential Revision: https://phab.enlightenment.org/D1157
This commit is contained in:
MinJeong Kim 2014-07-09 11:06:25 -04:00 committed by Chris Michael
parent 97c39e74cc
commit ed16127395
4 changed files with 68 additions and 21 deletions

View File

@ -2482,6 +2482,12 @@ _e_comp_wl_cb_hook_client_focus_set(void *data EINA_UNUSED, E_Client *ec)
E_FOCUS_METHOD_GLOBALLY_ACTIVE);
else if (!ec->icccm.take_focus)
e_grabinput_focus(e_client_util_win_get(ec), E_FOCUS_METHOD_PASSIVE);
if (ec->comp->wl_comp_data->kbd.focus != ec->wl_comp_data->surface)
{
ec->comp->wl_comp_data->kbd.focus = ec->wl_comp_data->surface;
e_comp_wl_data_device_keyboard_focus_set(ec->comp->wl_comp_data);
}
}
static void
@ -2498,6 +2504,9 @@ _e_comp_wl_cb_hook_client_focus_unset(void *data EINA_UNUSED, E_Client *ec)
}
_e_comp_wl_focus_check(ec->comp);
if (ec->comp->wl_comp_data->kbd.focus == ec->wl_comp_data->surface)
ec->comp->wl_comp_data->kbd.focus = NULL;
}
EAPI Eina_Bool

View File

@ -79,6 +79,7 @@ struct _E_Comp_Wl_Data
xkb_mod_mask_t mod_depressed, mod_latched, mod_locked;
xkb_layout_index_t mod_group;
struct wl_array keys;
struct wl_resource *focus;
} kbd;
struct

View File

@ -155,7 +155,7 @@ _e_comp_wl_data_device_destroy_selection_data_source(struct wl_listener *listene
{
E_Comp_Wl_Data *cdata;
E_Comp_Wl_Data_Source *source;
struct wl_resource *data_device_res;
struct wl_resource *data_device_res, *focus = NULL;
if (!(source = (E_Comp_Wl_Data_Source*)data))
return;
@ -166,13 +166,18 @@ _e_comp_wl_data_device_destroy_selection_data_source(struct wl_listener *listene
cdata->selection.data_source = NULL;
/* TODO: get data device from a focused surface */
data_device_res =
_e_comp_wl_data_find_for_client(cdata->mgr.data_resources,
wl_resource_get_client(source->resource));
if (cdata->kbd.enabled)
focus = cdata->kbd.focus;
if (data_device_res)
wl_data_device_send_selection(data_device_res, NULL);
if (focus)
{
data_device_res =
_e_comp_wl_data_find_for_client(cdata->mgr.data_resources,
wl_resource_get_client(source->resource));
if (data_device_res)
wl_data_device_send_selection(data_device_res, NULL);
}
wl_signal_emit(&cdata->selection.signal, cdata);
}
@ -221,7 +226,7 @@ _e_comp_wl_data_device_cb_selection_set(struct wl_client *client EINA_UNUSED, st
{
E_Comp_Wl_Data *cdata;
E_Comp_Wl_Data_Source *source, *sel_source;
struct wl_resource *offer_res, *data_device_res;
struct wl_resource *offer_res, *data_device_res, *focus = NULL;
if (!source_resource) return;
if (!(cdata = wl_resource_get_user_data(resource))) return;
@ -244,20 +249,26 @@ _e_comp_wl_data_device_cb_selection_set(struct wl_client *client EINA_UNUSED, st
cdata->selection.data_source = sel_source = source;
cdata->selection.serial = serial;
/* TODO: get data device from a focused surface */
data_device_res =
_e_comp_wl_data_find_for_client(cdata->mgr.data_resources,
wl_resource_get_client(source->resource));
if (cdata->kbd.enabled)
focus = cdata->kbd.focus;
if ((data_device_res) && (source))
if (focus)
{
offer_res =
_e_comp_wl_data_device_data_offer_create(source, data_device_res);
wl_data_device_send_selection(data_device_res, offer_res);
}
else if (data_device_res)
{
wl_data_device_send_selection(data_device_res, NULL);
data_device_res =
_e_comp_wl_data_find_for_client(cdata->mgr.data_resources,
wl_resource_get_client(focus));
if ((data_device_res) && (source))
{
offer_res =
_e_comp_wl_data_device_data_offer_create(source,
data_device_res);
wl_data_device_send_selection(data_device_res, offer_res);
}
else if (data_device_res)
{
wl_data_device_send_selection(data_device_res, NULL);
}
}
wl_signal_emit(&cdata->selection.signal, cdata);
@ -387,7 +398,32 @@ _e_comp_wl_data_cb_bind_manager(struct wl_client *client, void *data, uint32_t v
wl_resource_set_implementation(res, &_e_manager_interface, cdata, NULL);
}
EINTERN Eina_Bool
EINTERN void
e_comp_wl_data_device_keyboard_focus_set(E_Comp_Wl_Data *cdata)
{
struct wl_resource *data_device_res, *offer_res, *focus;
E_Comp_Wl_Data_Source *source;
if (!cdata->kbd.enabled) return;
focus = cdata->kbd.focus;
if (!focus) return;
data_device_res =
_e_comp_wl_data_find_for_client(cdata->mgr.data_resources,
wl_resource_get_client(focus));
if (!data_device_res) return;
source = (E_Comp_Wl_Data_Source*)cdata->selection.data_source;
if (source)
{
offer_res = _e_comp_wl_data_device_data_offer_create(source,
data_device_res);
wl_data_device_send_selection(data_device_res, offer_res);
}
}
EINTERN Eina_Bool
e_comp_wl_data_manager_init(E_Comp_Wl_Data *cdata)
{
/* check for valid compositor data */

View File

@ -26,6 +26,7 @@ struct _E_Comp_Wl_Data_Offer
struct wl_listener source_destroy_listener; //listener for destroy of source
};
EINTERN void e_comp_wl_data_device_keyboard_focus_set(E_Comp_Wl_Data *cdata);
EINTERN Eina_Bool e_comp_wl_data_manager_init(E_Comp_Wl_Data *cdata);
EINTERN void e_comp_wl_data_manager_shutdown(E_Comp_Wl_Data *cdata);