Ecore X: Added Xfixes selection notification support.

Now we can get notifications for changes in X selection. This is very useful
for text editors that want to disable their "paste" button when there's
nothing to paste.

SVN revision: 62205
This commit is contained in:
Tom Hacohen 2011-08-08 14:36:02 +00:00
parent b72850a06d
commit 6a2929e448
6 changed files with 130 additions and 6 deletions

View File

@ -371,6 +371,7 @@ typedef struct _Ecore_X_Event_Window_Mapping Ecore_X_Event_Window_Mapping;
typedef struct _Ecore_X_Event_Selection_Clear Ecore_X_Event_Selection_Clear;
typedef struct _Ecore_X_Event_Selection_Request Ecore_X_Event_Selection_Request;
typedef struct _Ecore_X_Event_Selection_Notify Ecore_X_Event_Selection_Notify;
typedef struct _Ecore_X_Event_Fixes_Selection_Notify Ecore_X_Event_Fixes_Selection_Notify;
typedef struct _Ecore_X_Selection_Data Ecore_X_Selection_Data;
typedef struct _Ecore_X_Selection_Data_Files Ecore_X_Selection_Data_Files;
typedef struct _Ecore_X_Selection_Data_Text Ecore_X_Selection_Data_Text;
@ -617,6 +618,24 @@ struct _Ecore_X_Event_Selection_Request
Ecore_X_Atom property;
};
typedef enum
{
ECORE_X_OWNER_CHANGE_REASON_NEW_OWNER,
ECORE_X_OWNER_CHANGE_REASON_DESTROY,
ECORE_X_OWNER_CHANGE_REASON_CLOSE
} Ecore_X_Owner_Change_Reason;
struct _Ecore_X_Event_Fixes_Selection_Notify
{
Ecore_X_Window win;
Ecore_X_Window owner;
Ecore_X_Time time;
Ecore_X_Time selection_time;
Ecore_X_Selection selection;
Ecore_X_Atom atom;
Ecore_X_Owner_Change_Reason reason;
};
struct _Ecore_X_Event_Selection_Notify
{
Ecore_X_Window win;
@ -898,6 +917,7 @@ EAPI extern int ECORE_X_EVENT_MAPPING_CHANGE;
EAPI extern int ECORE_X_EVENT_SELECTION_CLEAR;
EAPI extern int ECORE_X_EVENT_SELECTION_REQUEST;
EAPI extern int ECORE_X_EVENT_SELECTION_NOTIFY;
EAPI extern int ECORE_X_EVENT_FIXES_SELECTION_NOTIFY;
EAPI extern int ECORE_X_EVENT_CLIENT_MESSAGE;
EAPI extern int ECORE_X_EVENT_WINDOW_SHAPE;
EAPI extern int ECORE_X_EVENT_SCREENSAVER_NOTIFY;
@ -3002,6 +3022,16 @@ EAPI void ecore_x_region_picture_clip_set(Ecore_X_Region regi
int x_origin,
int y_origin);
/**
* xfixes selection notification request.
*
* This lets you choose which selections you want to get notifications for.
* @param selection the selection atom.
* @return EINA_TRUE on success, EINA_FALSE otherwise.
* @since 1.1.0
*/
EAPI Eina_Bool ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection);
/* XComposite Extension Support */
EAPI Eina_Bool ecore_x_composite_query(void);
EAPI void ecore_x_composite_redirect_window(Ecore_X_Window win,

View File

@ -130,6 +130,7 @@ EAPI int ECORE_X_EVENT_MAPPING_CHANGE = 0;
EAPI int ECORE_X_EVENT_SELECTION_CLEAR = 0;
EAPI int ECORE_X_EVENT_SELECTION_REQUEST = 0;
EAPI int ECORE_X_EVENT_SELECTION_NOTIFY = 0;
EAPI int ECORE_X_EVENT_FIXES_SELECTION_NOTIFY = 0;
EAPI int ECORE_X_EVENT_CLIENT_MESSAGE = 0;
EAPI int ECORE_X_EVENT_WINDOW_SHAPE = 0;
EAPI int ECORE_X_EVENT_SCREENSAVER_NOTIFY = 0;
@ -2059,14 +2060,37 @@ _ecore_xcb_event_handle_sync_alarm(xcb_generic_event_t *event)
static void
_ecore_xcb_event_handle_xfixes_selection_notify(xcb_generic_event_t *event __UNUSED__)
{
// xcb_xfixes_selection_notify_event_t *ev;
Ecore_X_Event_Fixes_Selection_Notify *e;
Ecore_X_Atom sel;
xcb_xfixes_selection_notify_event_t *ev;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
_ecore_xcb_event_last_mouse_move = EINA_FALSE;
// ev = (xcb_xfixes_selection_notify_event_t *)event;
ev = (xcb_xfixes_selection_notify_event_t *)event;
e = calloc(1, sizeof(*e));
if (!e)
return;
e->win = ev->window;
e->owner = ev->owner;
e->time = ev->timestamp;
e->selection_time = ev->selection_timestamp;
e->atom = sel = ev->selection;
if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
e->selection = ECORE_X_SELECTION_PRIMARY;
else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
e->selection = ECORE_X_SELECTION_SECONDARY;
else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
e->selection = ECORE_X_SELECTION_CLIPBOARD;
else
e->selection = ECORE_X_SELECTION_OTHER;
e->reason = ev->subtype;
ecore_event_add(ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, e, NULL, NULL);
} /* _ecore_x_event_handle_fixes_selection_notify */
// FIXME: TBD
}
static void

View File

@ -47,7 +47,10 @@ _ecore_xcb_xfixes_finalize(void)
if (reply)
{
if (reply->major_version >= 3)
_xfixes_avail = EINA_TRUE;
{
_xfixes_avail = EINA_TRUE;
ECORE_X_EVENT_FIXES_SELECTION_NOTIFY = ecore_event_type_new();
}
free(reply);
}
@ -57,6 +60,25 @@ _ecore_xcb_xfixes_finalize(void)
#endif
}
EAPI Eina_Bool
ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection)
{
#ifdef ECORE_XCB_XFIXES
if (_xfixes_avail)
{
xcb_xfixes_select_selection_input_checked(_ecore_xcb_conn,
/* FIXME: We need a way to know the root window. */
NULL,
selection,
XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE);
return EINA_TRUE;
}
#endif
return EINA_FALSE;
}
Eina_Bool
_ecore_xcb_xfixes_avail_get(void)
{

View File

@ -91,6 +91,7 @@ EAPI int ECORE_X_EVENT_MAPPING_CHANGE = 0;
EAPI int ECORE_X_EVENT_SELECTION_CLEAR = 0;
EAPI int ECORE_X_EVENT_SELECTION_REQUEST = 0;
EAPI int ECORE_X_EVENT_SELECTION_NOTIFY = 0;
EAPI int ECORE_X_EVENT_FIXES_SELECTION_NOTIFY = 0;
EAPI int ECORE_X_EVENT_CLIENT_MESSAGE = 0;
EAPI int ECORE_X_EVENT_WINDOW_SHAPE = 0;
EAPI int ECORE_X_EVENT_SCREENSAVER_NOTIFY = 0;

View File

@ -2107,9 +2107,34 @@ _ecore_x_event_handle_randr_notify(XEvent *xevent)
void
_ecore_x_event_handle_fixes_selection_notify(XEvent *event)
{
XFixesSelectionNotifyEvent *notify_event =
(XFixesSelectionNotifyEvent *) event;
Ecore_X_Event_Fixes_Selection_Notify *e;
Ecore_X_Atom sel;
_ecore_x_last_event_mouse_move = 0;
/* Nothing here yet */
event = NULL;
e = calloc(1, sizeof(*e));
if (!e)
return;
e->win = notify_event->window;
e->owner = notify_event->owner;
e->time = notify_event->timestamp;
e->selection_time = notify_event->selection_timestamp;
e->atom = sel = notify_event->selection;
if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
e->selection = ECORE_X_SELECTION_PRIMARY;
else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
e->selection = ECORE_X_SELECTION_SECONDARY;
else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
e->selection = ECORE_X_SELECTION_CLIPBOARD;
else
e->selection = ECORE_X_SELECTION_OTHER;
e->reason = notify_event->subtype;
ecore_event_add(ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, e, NULL, NULL);
} /* _ecore_x_event_handle_fixes_selection_notify */
#endif /* ifdef ECORE_XFIXES */

View File

@ -21,7 +21,11 @@ _ecore_x_fixes_init(void)
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (XFixesQueryVersion(_ecore_x_disp, &_fixes_major, &_fixes_minor))
_fixes_available = 1;
{
_fixes_available = 1;
ECORE_X_EVENT_FIXES_SELECTION_NOTIFY = ecore_event_type_new();
}
else
_fixes_available = 0;
@ -80,6 +84,24 @@ _ecore_x_rectangle_x_to_ecore(XRectangle *xrect, int num)
#endif /* ifdef ECORE_XFIXES */
EAPI Eina_Bool
ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection)
{
#ifdef ECORE_XFIXES
if (_fixes_available)
{
XFixesSelectSelectionInput (_ecore_x_disp,
DefaultRootWindow(_ecore_x_disp),
selection,
XFixesSetSelectionOwnerNotifyMask |
XFixesSelectionWindowDestroyNotifyMask |
XFixesSelectionClientCloseNotifyMask);
return EINA_TRUE;
}
#endif
return EINA_FALSE;
}
EAPI Ecore_X_Region
ecore_x_region_new(Ecore_X_Rectangle *rects, int num)
{