diff --git a/WINGs/WINGs/WINGs.h b/WINGs/WINGs/WINGs.h index e136efd4..c9810bfe 100644 --- a/WINGs/WINGs/WINGs.h +++ b/WINGs/WINGs/WINGs.h @@ -661,6 +661,9 @@ void WMNextEvent(Display *dpy, XEvent *event); void WMMaskEvent(Display *dpy, long mask, XEvent *event); +/* ....................................................................... */ + + Bool WMCreateSelectionHandler(WMView *view, Atom selection, Time timestamp, WMSelectionProcs *procs, void *cdata); @@ -671,6 +674,8 @@ Bool WMRequestSelection(WMView *view, Atom selection, Atom target, void *cdata); +extern char *WMSelectionOwnerDidChangeNotification; + /* ....................................................................... */ void WMSetViewDragSourceProcs(WMView *view, WMDragSourceProcs *procs); diff --git a/WINGs/selection.c b/WINGs/selection.c index f094f2c4..8a10ee05 100644 --- a/WINGs/selection.c +++ b/WINGs/selection.c @@ -9,6 +9,9 @@ #define MAX_PROPERTY_SIZE 8*1024 +char *WMSelectionOwnerDidChangeNotification = "WMSelectionOwnerDidChange"; + + typedef struct SelectionHandler { WMView *view; Atom selection; @@ -59,7 +62,7 @@ WMDeleteSelectionHandler(WMView *view, Atom selection, Time timestamp) if (!selHandlers) return; - //printf("deleting selection handler for %d\n", win); + printf("deleting selection handler for %d", win); WM_ITERATE_ARRAY(selHandlers, handler, iter) { if (handler->view == view @@ -68,14 +71,17 @@ WMDeleteSelectionHandler(WMView *view, Atom selection, Time timestamp) if (handler->flags.done_pending) { handler->flags.delete_pending = 1; - return; + puts(": postponed because still pending"); + return; } - //puts("found & removed"); + printf(": found & removed"); WMRemoveFromArray(selHandlers, handler); break; } } + printf("\n"); + XGrabServer(dpy); if (XGetSelectionOwner(dpy, selection) == win) { XSetSelectionOwner(dpy, selection, None, timestamp); @@ -343,7 +349,18 @@ handleNotifyEvent(XEvent *event) void W_HandleSelectionEvent(XEvent *event) { - //printf("%d received %d\n", event->xany.window, event->type); + printf("%d received selection ", event->xany.window); + switch(event->type) { + case SelectionNotify: + puts("notify"); break; + case SelectionRequest: + puts("request"); break; + case SelectionClear: + puts("clear"); break; + default: + puts("unknown"); break; + } + if (event->type == SelectionNotify) { handleNotifyEvent(event); } else { @@ -366,10 +383,12 @@ WMCreateSelectionHandler(WMView *view, Atom selection, Time timestamp, return False; } - //printf("created selection handler for %d\n", W_VIEW_DRAWABLE(view)); - handler = malloc(sizeof(SelectionHandler)); - if (handler == NULL) - return False; + WMPostNotificationName(WMSelectionOwnerDidChangeNotification, + (void*)selection, (void*)view); + + printf("created selection handler for %d\n", W_VIEW_DRAWABLE(view)); + + handler = wmalloc(sizeof(SelectionHandler)); handler->view = view; handler->selection = selection; @@ -381,9 +400,9 @@ WMCreateSelectionHandler(WMView *view, Atom selection, Time timestamp, if (selHandlers == NULL) { selHandlers = WMCreateArrayWithDestructor(4, wfree); } - + WMAddToArray(selHandlers, handler); - + return True; } diff --git a/WINGs/wtextfield.c b/WINGs/wtextfield.c index b071c080..087a2e23 100644 --- a/WINGs/wtextfield.c +++ b/WINGs/wtextfield.c @@ -115,24 +115,24 @@ static void didResizeTextField(); struct W_ViewDelegate _TextFieldViewDelegate = { NULL, - NULL, - didResizeTextField, - NULL, - NULL + NULL, + didResizeTextField, + NULL, + NULL }; -static void lostHandler(WMView *view, Atom selection, void *cdata); +static void lostSelection(WMView *view, Atom selection, void *cdata); static WMData *requestHandler(WMView *view, Atom selection, Atom target, - void *cdata, Atom *type); + void *cdata, Atom *type); static WMSelectionProcs selectionHandler = { requestHandler, - lostHandler, - NULL + lostSelection, + NULL }; @@ -234,7 +234,7 @@ decrToFit(TextField *tPtr) static WMData* requestHandler(WMView *view, Atom selection, Atom target, void *cdata, - Atom *type) + Atom *type) { TextField *tPtr = view->self; int count; @@ -281,23 +281,32 @@ requestHandler(WMView *view, Atom selection, Atom target, void *cdata, static void -lostHandler(WMView *view, Atom selection, void *cdata) +lostSelection(WMView *view, Atom selection, void *cdata) { TextField *tPtr = (WMTextField*)view->self; - //WMDeleteSelectionHandler(view, XA_PRIMARY, CurrentTime); - tPtr->flags.ownsSelection = 0; - tPtr->selection.count = 0; - paintTextField(tPtr); + if (tPtr->flags.ownsSelection) { + WMDeleteSelectionHandler(view, selection, CurrentTime); + tPtr->flags.ownsSelection = 0; + } + if (tPtr->selection.count != 0) { + tPtr->selection.count = 0; + paintTextField(tPtr); + } } static void -_notification(void *observerData, WMNotification *notification) +selectionNotification(void *observerData, WMNotification *notification) { - WMTextField *to = (WMTextField*)observerData; - WMTextField *tw = (WMTextField*)WMGetNotificationClientData(notification); - if (to != tw) lostHandler(to->view, XA_PRIMARY, NULL); + WMView *observerView = (WMView*)observerData; + WMView *newOwnerView = (WMView*)WMGetNotificationClientData(notification); + + if (observerView != newOwnerView) { + //if (tPtr->flags.ownsSelection) + // WMDeleteSelectionHandler(observerView, XA_PRIMARY, CurrentTime); + lostSelection(observerView, XA_PRIMARY, NULL); + } } @@ -348,8 +357,10 @@ WMCreateTextField(WMWidget *parent) WMCreateEventHandler(tPtr->view, EnterWindowMask|LeaveWindowMask |ButtonReleaseMask|ButtonPressMask|KeyPressMask|Button1MotionMask, handleTextFieldActionEvents, tPtr); - - WMAddNotificationObserver(_notification, tPtr, "_lostOwnership", tPtr); + + WMAddNotificationObserver(selectionNotification, tPtr->view, + WMSelectionOwnerDidChangeNotification, + (void*)XA_PRIMARY); tPtr->flags.cursorOn = 1; @@ -1279,7 +1290,7 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event) /* Do not allow text selection in secure text fields */ if (cancelSelection || tPtr->flags.secure) { - lostHandler(tPtr->view, XA_PRIMARY, NULL); + lostSelection(tPtr->view, XA_PRIMARY, NULL); if (tPtr->selection.count) { tPtr->selection.count = 0; @@ -1291,8 +1302,6 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event) tPtr->selection.count = tPtr->cursorPosition - tPtr->selection.position; - WMPostNotificationName("_lostOwnership", NULL, tPtr); - refresh = 1; } } @@ -1535,7 +1544,7 @@ handleTextFieldActionEvents(XEvent *event, void *data) break; } - if (tPtr->selection.count != 0) { + if (!tPtr->flags.secure && tPtr->selection.count!=0) { int start, count; XRotateBuffers(dpy, 1); @@ -1558,23 +1567,19 @@ handleTextFieldActionEvents(XEvent *event, void *data) paintTextField(tPtr); if (!tPtr->flags.ownsSelection) { - WMCreateSelectionHandler(tPtr->view, - XA_PRIMARY, - event->xbutton.time, - &selectionHandler, NULL); - tPtr->flags.ownsSelection = 1; - //puts("lost ownership"); - WMPostNotificationName("_lostOwnership", NULL, tPtr); + tPtr->flags.ownsSelection = + WMCreateSelectionHandler(tPtr->view, + XA_PRIMARY, + event->xbutton.time, + &selectionHandler, NULL); } } else if (!tPtr->flags.secure && tPtr->selection.count!=0 && !tPtr->flags.ownsSelection) { - WMCreateSelectionHandler(tPtr->view, - XA_PRIMARY, - event->xbutton.time, - &selectionHandler, NULL); - tPtr->flags.ownsSelection = 1; - //puts("lost ownership"); - WMPostNotificationName("_lostOwnership", NULL, tPtr); + tPtr->flags.ownsSelection = + WMCreateSelectionHandler(tPtr->view, + XA_PRIMARY, + event->xbutton.time, + &selectionHandler, NULL); } lastButtonReleasedEvent = event->xbutton.time; @@ -1593,6 +1598,7 @@ destroyTextField(TextField *tPtr) #endif WMReleaseFont(tPtr->font); + // use lostSelection() instead of WMDeleteSelectionHandler aici? WMDeleteSelectionHandler(tPtr->view, XA_PRIMARY, CurrentTime); WMRemoveNotificationObserver(tPtr);