1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-19 12:28:22 +01:00

added responder chain alike stuff for relaying kbd events from widget to widget

This commit is contained in:
kojima
2001-01-18 02:00:56 +00:00
parent 1b587b01ee
commit bb886be82e
9 changed files with 227 additions and 132 deletions

View File

@@ -433,6 +433,12 @@ int WMGetTableViewClickedRow(WMTableView *table)
}
WMArray *WMGetTableViewSelectedRows(WMTableView *table)
{
return table->selectedRows;
}
WMView *WMGetTableViewDocumentView(WMTableView *table)
{
return table->tableView;

View File

@@ -77,6 +77,8 @@ void *WMGetTableViewClickedColumn(WMTableView *table);
int WMGetTableViewClickedRow(WMTableView *table);
WMArray *WMGetTableViewSelectedRows(WMTableView *table);
WMView *WMGetTableViewDocumentView(WMTableView *table);
void WMEditTableViewRow(WMTableView *table, int row);

View File

@@ -7,7 +7,7 @@
#include <WINGs/WUtil.h>
#include <X11/Xlib.h>
#define WINGS_H_VERSION 20000521
#define WINGS_H_VERSION 20010117
#ifdef __cplusplus
@@ -849,6 +849,10 @@ WMPoint WMGetViewScreenPosition(WMView *view);
WMWidget *WMWidgetOfView(WMView *view);
void WMSetViewNextResponder(WMView *view, WMView *responder);
void WMRelayToNextResponder(WMView *view, XEvent *event);
/* notifications */
extern char *WMViewSizeDidChangeNotification;

View File

@@ -8,7 +8,7 @@
#include <WINGs/WINGs.h>
#if WINGS_H_VERSION < 20000521
#if WINGS_H_VERSION < 20010117
#error There_is_an_old_WINGs.h_file_somewhere_in_your_system._Please_remove_it.
#endif
@@ -321,6 +321,8 @@ typedef struct W_View {
struct W_View *nextFocusChain; /* next/prev in focus chain */
struct W_View *prevFocusChain;
struct W_View *nextResponder; /* next to receive keyboard events */
struct W_View *parent; /* parent WMView */
@@ -500,7 +502,7 @@ void W_SetFocusOfToplevel(W_View *toplevel, W_View *view);
W_View *W_FocusedViewOfToplevel(W_View *view);
void W_SetFocusOfTopLevel(W_View *toplevel, W_View *view);
void W_ReleaseView(WMView *view);
WMView *W_RetainView(WMView *view);

View File

@@ -523,6 +523,36 @@ W_CallDestroyHandlers(W_View *view)
}
void
WMSetViewNextResponder(WMView *view, WMView *responder)
{
/* set the widget to receive keyboard events that aren't handled
* by this widget */
view->nextResponder = responder;
}
void
WMRelayToNextResponder(WMView *view, XEvent *event)
{
unsigned long mask = eventMasks[event->xany.type];
if (view->nextResponder) {
WMView *next = view->nextResponder;
W_EventHandler *hPtr;
WMBagIterator iter;
WM_ITERATE_BAG(next->eventHandlers, hPtr, iter) {
if ((hPtr->eventMask & mask)) {
(*hPtr->proc)(event, hPtr->clientData);
}
}
}
}
int
WMHandleEvent(XEvent *event)
{
@@ -627,7 +657,7 @@ WMHandleEvent(XEvent *event)
(*hPtr->proc)(event, hPtr->clientData);
}
}
#if 0
/* pass the event to the top level window of the widget */
/* TODO: change this to a responder chain */
if (view->parent != NULL) {
@@ -641,7 +671,7 @@ WMHandleEvent(XEvent *event)
}
}
}
#endif
/* save button click info to track double-clicks */
if (view->screen->ignoreNextDoubleClick) {
view->screen->ignoreNextDoubleClick = 0;

View File

@@ -571,10 +571,6 @@ static void
popDownMenu(PopUpButton *bPtr)
{
W_UnmapView(bPtr->menuView);
/* free the background pixmap used to draw the menu contents */
XSetWindowBackgroundPixmap(bPtr->view->screen->display,
bPtr->menuView->window, None);
}

View File

@@ -2312,6 +2312,8 @@ R_imaGFX: if(tb->next) {
}
else if (control_pressed && buffer[0] == '')
XBell(tPtr->view->screen->display, 0);
else
WMRelayToNextResponder(tPtr->view, event);
}
if (!control_pressed && tPtr->flags.ownsSelection)

View File

@@ -998,45 +998,67 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
int count, refresh = 0;
int control_pressed = 0;
int cancelSelection = 1;
Bool shifted, controled, modified;
Bool relay = True;
/*printf("(%d,%d) -> ", tPtr->selection.position, tPtr->selection.count);*/
if (((XKeyEvent *) event)->state & WM_EMACSKEYMASK)
control_pressed = 1;
shifted = event->xkey.state & ShiftMask;
controled = event->xkey.state & ControlMask;
if ((event->xkey.state & ~(ShiftMask|ControlMask)) != 0) {
modified = True;
} else {
modified = False;
}
count = XLookupString(&event->xkey, buffer, 63, &ksym, NULL);
buffer[count] = '\0';
switch (ksym) {
case XK_Tab:
#ifdef XK_ISO_Left_Tab
case XK_ISO_Left_Tab:
#endif
if (event->xkey.state & ShiftMask) {
if (tPtr->view->prevFocusChain) {
W_SetFocusOfTopLevel(W_TopLevelOfView(tPtr->view),
tPtr->view->prevFocusChain);
tPtr->flags.notIllegalMovement = 1;
}
data = (void*)WMBacktabTextMovement;
} else {
if (tPtr->view->nextFocusChain) {
W_SetFocusOfTopLevel(W_TopLevelOfView(tPtr->view),
tPtr->view->nextFocusChain);
tPtr->flags.notIllegalMovement = 1;
}
data = (void*)WMTabTextMovement;
if (!controled && !modified) {
if (shifted) {
if (tPtr->view->prevFocusChain) {
W_SetFocusOfTopLevel(W_TopLevelOfView(tPtr->view),
tPtr->view->prevFocusChain);
tPtr->flags.notIllegalMovement = 1;
}
data = (void*)WMBacktabTextMovement;
} else {
if (tPtr->view->nextFocusChain) {
W_SetFocusOfTopLevel(W_TopLevelOfView(tPtr->view),
tPtr->view->nextFocusChain);
tPtr->flags.notIllegalMovement = 1;
}
data = (void*)WMTabTextMovement;
}
textEvent = WMTextDidEndEditingNotification;
relay = False;
}
textEvent = WMTextDidEndEditingNotification;
break;
case XK_Escape:
data = (void*)WMEscapeTextMovement;
textEvent = WMTextDidEndEditingNotification;
if (!shifted && !controled && !modified) {
data = (void*)WMEscapeTextMovement;
textEvent = WMTextDidEndEditingNotification;
relay = False;
}
break;
case XK_Return:
data = (void*)WMReturnTextMovement;
textEvent = WMTextDidEndEditingNotification;
if (!shifted && !controled && !modified) {
data = (void*)WMReturnTextMovement;
textEvent = WMTextDidEndEditingNotification;
relay = False;
}
break;
case WM_EMACSKEY_LEFT:
@@ -1047,26 +1069,30 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
case XK_KP_Left:
#endif
case XK_Left:
if (tPtr->cursorPosition > 0) {
paintCursor(tPtr);
if (event->xkey.state & ControlMask) {
int i = tPtr->cursorPosition - 1;
while (i > 0 && tPtr->text[i] != ' ') i--;
while (i > 0 && tPtr->text[i] == ' ') i--;
tPtr->cursorPosition = (i > 0) ? i + 1 : 0;
} else
tPtr->cursorPosition--;
if (tPtr->cursorPosition < tPtr->viewPosition) {
tPtr->viewPosition = tPtr->cursorPosition;
refresh = 1;
} else
if (!modified) {
if (tPtr->cursorPosition > 0) {
paintCursor(tPtr);
if (event->xkey.state & ControlMask) {
int i = tPtr->cursorPosition - 1;
while (i > 0 && tPtr->text[i] != ' ') i--;
while (i > 0 && tPtr->text[i] == ' ') i--;
tPtr->cursorPosition = (i > 0) ? i + 1 : 0;
} else
tPtr->cursorPosition--;
if (tPtr->cursorPosition < tPtr->viewPosition) {
tPtr->viewPosition = tPtr->cursorPosition;
refresh = 1;
} else
paintCursor(tPtr);
}
if (event->xkey.state & ShiftMask)
cancelSelection = 0;
relay = False;
}
if (event->xkey.state & ShiftMask)
cancelSelection = 0;
break;
case WM_EMACSKEY_RIGHT:
@@ -1077,30 +1103,34 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
case XK_KP_Right:
#endif
case XK_Right:
if (tPtr->cursorPosition < tPtr->textLen) {
paintCursor(tPtr);
if (event->xkey.state & ControlMask) {
int i = tPtr->cursorPosition;
while (tPtr->text[i] && tPtr->text[i] != ' ') i++;
while (tPtr->text[i] == ' ') i++;
tPtr->cursorPosition = i;
} else {
tPtr->cursorPosition++;
}
while (WMWidthOfString(tPtr->font,
&(tPtr->text[tPtr->viewPosition]),
tPtr->cursorPosition-tPtr->viewPosition)
> tPtr->usableWidth) {
tPtr->viewPosition++;
refresh = 1;
}
if (!refresh)
if (!modified) {
if (tPtr->cursorPosition < tPtr->textLen) {
paintCursor(tPtr);
if (event->xkey.state & ControlMask) {
int i = tPtr->cursorPosition;
while (tPtr->text[i] && tPtr->text[i] != ' ') i++;
while (tPtr->text[i] == ' ') i++;
tPtr->cursorPosition = i;
} else {
tPtr->cursorPosition++;
}
while (WMWidthOfString(tPtr->font,
&(tPtr->text[tPtr->viewPosition]),
tPtr->cursorPosition-tPtr->viewPosition)
> tPtr->usableWidth) {
tPtr->viewPosition++;
refresh = 1;
}
if (!refresh)
paintCursor(tPtr);
}
if (event->xkey.state & ShiftMask)
cancelSelection = 0;
relay = False;
}
if (event->xkey.state & ShiftMask)
cancelSelection = 0;
break;
case WM_EMACSKEY_HOME:
@@ -1111,17 +1141,21 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
case XK_KP_Home:
#endif
case XK_Home:
if (tPtr->cursorPosition > 0) {
paintCursor(tPtr);
tPtr->cursorPosition = 0;
if (tPtr->viewPosition > 0) {
tPtr->viewPosition = 0;
refresh = 1;
} else
if (!modified && !controled) {
if (tPtr->cursorPosition > 0) {
paintCursor(tPtr);
tPtr->cursorPosition = 0;
if (tPtr->viewPosition > 0) {
tPtr->viewPosition = 0;
refresh = 1;
} else
paintCursor(tPtr);
}
if (event->xkey.state & ShiftMask)
cancelSelection = 0;
relay = False;
}
if (event->xkey.state & ShiftMask)
cancelSelection = 0;
break;
case WM_EMACSKEY_END:
@@ -1132,22 +1166,26 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
case XK_KP_End:
#endif
case XK_End:
if (tPtr->cursorPosition < tPtr->textLen) {
paintCursor(tPtr);
tPtr->cursorPosition = tPtr->textLen;
tPtr->viewPosition = 0;
while (WMWidthOfString(tPtr->font,
&(tPtr->text[tPtr->viewPosition]),
tPtr->textLen-tPtr->viewPosition)
> tPtr->usableWidth) {
tPtr->viewPosition++;
refresh = 1;
}
if (!refresh)
if (!modified && !controled) {
if (tPtr->cursorPosition < tPtr->textLen) {
paintCursor(tPtr);
tPtr->cursorPosition = tPtr->textLen;
tPtr->viewPosition = 0;
while (WMWidthOfString(tPtr->font,
&(tPtr->text[tPtr->viewPosition]),
tPtr->textLen-tPtr->viewPosition)
> tPtr->usableWidth) {
tPtr->viewPosition++;
refresh = 1;
}
if (!refresh)
paintCursor(tPtr);
}
if (event->xkey.state & ShiftMask)
cancelSelection = 0;
relay = False;
}
if (event->xkey.state & ShiftMask)
cancelSelection = 0;
break;
case WM_EMACSKEY_BS:
@@ -1155,17 +1193,21 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
goto normal_key;
}
case XK_BackSpace:
if (tPtr->selection.count) {
WMDeleteTextFieldRange(tPtr, tPtr->selection);
data = (void*)WMDeleteTextEvent;
textEvent = WMTextDidChangeNotification;
} else if (tPtr->cursorPosition > 0) {
WMRange range;
range.position = tPtr->cursorPosition - 1;
range.count = 1;
WMDeleteTextFieldRange(tPtr, range);
data = (void*)WMDeleteTextEvent;
textEvent = WMTextDidChangeNotification;
if (!modified && !shifted && !controled) {
if (tPtr->selection.count) {
WMDeleteTextFieldRange(tPtr, tPtr->selection);
data = (void*)WMDeleteTextEvent;
textEvent = WMTextDidChangeNotification;
} else if (tPtr->cursorPosition > 0) {
WMRange range;
range.position = tPtr->cursorPosition - 1;
range.count = 1;
WMDeleteTextFieldRange(tPtr, range);
data = (void*)WMDeleteTextEvent;
textEvent = WMTextDidChangeNotification;
}
relay = False;
}
break;
@@ -1177,34 +1219,46 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
case XK_KP_Delete:
#endif
case XK_Delete:
if (tPtr->selection.count) {
WMDeleteTextFieldRange(tPtr, tPtr->selection);
data = (void*)WMDeleteTextEvent;
textEvent = WMTextDidChangeNotification;
} else if (tPtr->cursorPosition < tPtr->textLen) {
WMRange range;
range.position = tPtr->cursorPosition;
range.count = 1;
WMDeleteTextFieldRange(tPtr, range);
data = (void*)WMDeleteTextEvent;
textEvent = WMTextDidChangeNotification;
if (!modified && !controled && !shifted) {
if (tPtr->selection.count) {
WMDeleteTextFieldRange(tPtr, tPtr->selection);
data = (void*)WMDeleteTextEvent;
textEvent = WMTextDidChangeNotification;
} else if (tPtr->cursorPosition < tPtr->textLen) {
WMRange range;
range.position = tPtr->cursorPosition;
range.count = 1;
WMDeleteTextFieldRange(tPtr, range);
data = (void*)WMDeleteTextEvent;
textEvent = WMTextDidChangeNotification;
}
relay = False;
}
break;
normal_key:
default:
if (count > 0 && isprint(buffer[0])) {
if (tPtr->selection.count)
WMDeleteTextFieldRange(tPtr, tPtr->selection);
WMInsertTextFieldText(tPtr, buffer, tPtr->cursorPosition);
data = (void*)WMInsertTextEvent;
textEvent = WMTextDidChangeNotification;
} else {
/* should we rather break and goto cancel selection below? -Dan */
return;
if (!controled && !modified) {
if (count > 0 && isprint(buffer[0])) {
if (tPtr->selection.count)
WMDeleteTextFieldRange(tPtr, tPtr->selection);
WMInsertTextFieldText(tPtr, buffer, tPtr->cursorPosition);
data = (void*)WMInsertTextEvent;
textEvent = WMTextDidChangeNotification;
relay = False;
}
}
break;
}
if (relay) {
WMRelayToNextResponder(W_VIEW(tPtr), event);
return;
}
if (!cancelSelection) {
if (tPtr->selection.count != tPtr->cursorPosition - tPtr->selection.position) {
@@ -1335,11 +1389,8 @@ handleTextFieldActionEvents(XEvent *event, void *data)
}
if (tPtr->flags.enabled && tPtr->flags.focused) {
handleTextFieldKeyPress(tPtr, event);
XGrabPointer(dpy, W_VIEW(tPtr)->window, False,
PointerMotionMask|ButtonPressMask|ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, None,
W_VIEW(tPtr)->screen->invisibleCursor,
CurrentTime);
XDefineCursor(dpy, W_VIEW(tPtr)->window,
W_VIEW(tPtr)->screen->invisibleCursor);
tPtr->flags.pointerGrabbed = 1;
}
break;
@@ -1348,7 +1399,8 @@ handleTextFieldActionEvents(XEvent *event, void *data)
if (tPtr->flags.pointerGrabbed) {
tPtr->flags.pointerGrabbed = 0;
XUngrabPointer(dpy, CurrentTime);
XDefineCursor(dpy, W_VIEW(tPtr)->window,
W_VIEW(tPtr)->screen->textCursor);
}
if (tPtr->flags.waitingSelection) {
return;
@@ -1393,7 +1445,8 @@ handleTextFieldActionEvents(XEvent *event, void *data)
case ButtonPress:
if (tPtr->flags.pointerGrabbed) {
tPtr->flags.pointerGrabbed = 0;
XUngrabPointer(dpy, CurrentTime);
XDefineCursor(dpy, W_VIEW(tPtr)->window,
W_VIEW(tPtr)->screen->textCursor);
break;
}
@@ -1466,7 +1519,8 @@ handleTextFieldActionEvents(XEvent *event, void *data)
case ButtonRelease:
if (tPtr->flags.pointerGrabbed) {
tPtr->flags.pointerGrabbed = 0;
XUngrabPointer(dpy, CurrentTime);
XDefineCursor(dpy, W_VIEW(tPtr)->window,
W_VIEW(tPtr)->screen->textCursor);
}
if (tPtr->flags.waitingSelection) {
break;

View File

@@ -673,7 +673,6 @@ W_RetainView(WMView *view)
}
void
W_ReleaseView(WMView *view)
{