The following patch improves the cursor setting code.
The new code will set the cursor on all windows simultaneously
instead of one at the time. This simplifies the code.
Notes on the patch:
* The blank cursor is used to fake an hidden cursor.
Question: It might be better to add this as a predefined cursor
in the NSCursor class. However, the blank cursor is an
implementation artifect, so maybe it should not be added.
I have a slight preference for adding it to the NSCursor class.
* It uncovers a few minor other bugs.
- Moving (not dragging) a Text field in Gorm leaves the cursor
as an IBeam cursor.
- If the cursor is not the standard cursor and you create a new
window (with a shortcut) under the cursor. The cursor is not
reset to the standard cursor.
and perhaps some more.
Wim Oudshoorn.
2001-12-16 Willem Rein Oudshoorn <[EMAIL PROTECTED]>
* xgps/Source/SharedX/XGGeneric.h: removed currentMouseWindow instance variable
* xgps/Source/SharedX/XGContextEvent.m ([XGContext
-receivedEvent:type:extra:forMode:]):
removed cursor update code in EnterNotify and LeaveNotify.
* xgps/Headers/gnustep/xgps/XGContextWindow.h: removed unused instance
variable `cursor'
and added _initializeCursorForXWindow: declaration.
* xgps/Source/SharedX/XGDragView.m ([XGDragView -_setCursor]): fixed comment
([XGDragView -_handleEventDuringDragging:theEvent]): GSAppKitDraggingStatus
now
only updates cursor when targetMask changes.
* xgps/Source/SharedX/XGContextWindow.m ([XGContext -_blankCursor]): new method
([XGContext -_initializeCursorForXWindow:win]): new method
([XGContext -_DPSsetcursor::]): rewritten
([XGContext -DPSwindow::::::]): cursor initialization changed
([XGContext -DPShidecursor]): refactored to use _blankCursor
Index: Headers/gnustep/xgps/XGContextWindow.h
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/xgps/Headers/gnustep/xgps/XGContextWindow.h,v
retrieving revision 1.12
diff -c -r1.12 XGContextWindow.h
*** Headers/gnustep/xgps/XGContextWindow.h 3 Dec 2001 04:32:33 -0000 1.12
--- Headers/gnustep/xgps/XGContextWindow.h 16 Dec 2001 20:19:47 -0000
***************
*** 87,93 ****
int boff;
Atom protocols[4];
int numProtocols;
- Cursor cursor;
} gswindow_device_t;
@interface XGContext (DPSWindow)
--- 87,92 ----
***************
*** 96,101 ****
--- 95,101 ----
+ (gswindow_device_t *) _windowWithTag: (int)windowNumber;
- (void) _addExposedRectangle: (XRectangle)rectangle : (int)win;
- (void) _processExposedRectangles: (int)win;
+ - (void) _initializeCursorForXWindow: (Window) win;
/* This needs to go in NSGraphicsContext */
- (void) _DPSsetcursor: (Cursor)c : (BOOL)set;
Index: Source/SharedX/XGContextEvent.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/xgps/Source/SharedX/XGContextEvent.m,v
retrieving revision 1.78
diff -c -r1.78 XGContextEvent.m
*** Source/SharedX/XGContextEvent.m 7 Dec 2001 05:06:14 -0000 1.78
--- Source/SharedX/XGContextEvent.m 16 Dec 2001 20:19:51 -0000
***************
*** 805,823 ****
case EnterNotify:
NSDebugLLog(@"NSEvent", @"%d EnterNotify\n",
xEvent.xcrossing.window);
- generic.currentMouseWindow = xEvent.xcrossing.window;
- /* NSCursor's are global, while X cursors are local to
- a window. We need to check to see if the new window
- has the current cursor set, and set it if it doesn't.
- Hopefully this doesn't take too much time... */
- [self _DPSsetcursor: None : YES];
break;
// when the pointer leaves a window
case LeaveNotify:
NSDebugLLog(@"NSEvent", @"%d LeaveNotify\n",
xEvent.xcrossing.window);
- generic.currentMouseWindow = None;
break;
// the visibility of a window has changed
--- 805,816 ----
Index: Source/SharedX/XGContextWindow.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/xgps/Source/SharedX/XGContextWindow.m,v
retrieving revision 1.87
diff -c -r1.87 XGContextWindow.m
*** Source/SharedX/XGContextWindow.m 11 Dec 2001 04:37:44 -0000 1.87
--- Source/SharedX/XGContextWindow.m 16 Dec 2001 20:19:56 -0000
***************
*** 1003,1009 ****
window->buffer = 0;
window->alpha_buffer = 0;
! window->cursor = None;
/*
* FIXME - should this be protected by a lock for thread safety?
* generate a unique tag for this new window.
--- 1003,1011 ----
window->buffer = 0;
window->alpha_buffer = 0;
! // make sure that new window has the correct cursor
! [self _initializeCursorForXWindow: window->ident];
!
/*
* FIXME - should this be protected by a lock for thread safety?
* generate a unique tag for this new window.
***************
*** 2101,2154 ****
static Cursor xgps_blank_cursor = None;
static BOOL cursor_hidden = NO;
- (void) _DPSsetcursor: (Cursor)c : (BOOL)set
{
Window win;
! win = None;
! if (generic.currentMouseWindow != None)
{
! gswindow_device_t *window;
! win = generic.currentMouseWindow;
! window = [XGContext _windowForXWindow: win];
!
! /* This might occur when the mouse enters a window and we want
! to make sure the cursor is set on that window */
! if (window && c == None && set)
! {
! xgps_cursor_id_t *current = [[NSCursor currentCursor] _cid];
! if (current)
! {
! if (current->c == window->cursor)
! return;
! else
! c = current->c;
! }
! }
!
! /* If the current cursor is already set on this window, don't
! set it again, save the current cursor also. Technically, this
! could be stack based, but it's really not that important, this
! just saves a little bit of time if we happen to be setting the
! same cursor on a window over and over (like for DnD). */
! if (window)
! {
! if (set && window->cursor == c)
! return;
!
! if (set)
! window->cursor = c;
! else
! window->cursor = None;
! }
}
- if (win == None)
- return;
-
- if (set)
- XDefineCursor(XDPY, win, c);
- else
- XUndefineCursor(XDPY, win);
}
#define ALPHA_THRESHOLD 158
--- 2103,2177 ----
static Cursor xgps_blank_cursor = None;
static BOOL cursor_hidden = NO;
+ - (Cursor) _blankCursor
+ {
+ if (xgps_blank_cursor == None)
+ {
+ Pixmap shape, mask;
+ XColor black, white;
+
+ shape = XCreatePixmapFromBitmapData(XDPY, XDRW,
+ xgps_blank_cursor_bits,
+ 16, 16, 1, 0, 1);
+ mask = XCreatePixmapFromBitmapData(XDPY, XDRW,
+ xgps_blank_cursor_bits,
+ 16, 16, 1, 0, 1);
+ black.red = black.green = black.blue = 0;
+ black = [self xColorFromColor: black];
+ white.red = white.green = white.blue = 65535;
+ white = [self xColorFromColor: white];
+
+ xgps_blank_cursor = XCreatePixmapCursor(XDPY, shape, mask,
+ &white, &black, 0, 0);
+ XFreePixmap(XDPY, shape);
+ XFreePixmap(XDPY, mask);
+ }
+ return xgps_blank_cursor;
+ }
+
+ /*
+ set the cursor for a newly created window.
+ */
+
+ - (void) _initializeCursorForXWindow: (Window) win
+ {
+ if (cursor_hidden)
+ {
+ XDefineCursor (XDPY, win, [self _blankCursor]);
+ }
+ else
+ {
+ xgps_cursor_id_t *cid = [[NSCursor currentCursor] _cid];
+
+ XDefineCursor (XDPY, win, cid->c);
+ }
+ }
+
+
+ /*
+ set cursor on all XWindows we own. if `set' is NO
+ the cursor is unset on all windows.
+ Normally the cursor `c' correspond to the [NSCursor currentCursor]
+ The only exception should be when the cursor is hidden.
+ In that case `c' will be a blank cursor.
+ */
+
- (void) _DPSsetcursor: (Cursor)c : (BOOL)set
{
Window win;
+ NSMapEnumerator enumerator;
+ gswindow_device_t *d;
! NSDebugLLog (@"NSCursor", @"_DPSsetcursor: cursor = %p, set = %d", c, set);
!
! enumerator = NSEnumerateMapTable (windowmaps);
! while (NSNextMapEnumeratorPair (&enumerator, (void**)&win, (void**)&d) == YES)
{
! if (set)
! XDefineCursor(XDPY, win, c);
! else
! XUndefineCursor(XDPY, win);
}
}
#define ALPHA_THRESHOLD 158
***************
*** 2279,2309 ****
- (void) DPShidecursor
{
- Pixmap shape, mask;
- XColor black, white;
-
if (cursor_hidden)
return;
! if (xgps_blank_cursor == None)
! {
! shape = XCreatePixmapFromBitmapData(XDPY, XDRW,
! xgps_blank_cursor_bits,
! 16, 16, 1, 0, 1);
! mask = XCreatePixmapFromBitmapData(XDPY, XDRW,
! xgps_blank_cursor_bits,
! 16, 16, 1, 0, 1);
! black.red = black.green = black.blue = 0;
! black = [self xColorFromColor: black];
! white.red = white.green = white.blue = 65535;
! white = [self xColorFromColor: white];
!
! xgps_blank_cursor = XCreatePixmapCursor(XDPY, shape, mask,
! &white, &black, 0, 0);
! XFreePixmap(XDPY, shape);
! XFreePixmap(XDPY, mask);
! }
! [self _DPSsetcursor: xgps_blank_cursor : YES];
cursor_hidden = YES;
}
--- 2302,2311 ----
- (void) DPShidecursor
{
if (cursor_hidden)
return;
! [self _DPSsetcursor: [self _blankCursor] : YES];
cursor_hidden = YES;
}
Index: Source/SharedX/XGDragView.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/xgps/Source/SharedX/XGDragView.m,v
retrieving revision 1.1
diff -c -r1.1 XGDragView.m
*** Source/SharedX/XGDragView.m 3 Dec 2001 04:32:33 -0000 1.1
--- Source/SharedX/XGDragView.m 16 Dec 2001 20:19:58 -0000
***************
*** 419,425 ****
/*
_setCursor examines the state of the dragging and update
! the cursor accordingly. It will save the current cursor,
if you want to keep the original you have to save it yourself.
The code recogines 4 cursors:
--- 419,425 ----
/*
_setCursor examines the state of the dragging and update
! the cursor accordingly. It will not save the current cursor,
if you want to keep the original you have to save it yourself.
The code recogines 4 cursors:
***************
*** 696,704 ****
NSDebugLLog(@"NSDragging", @"got GSAppKitDraggingStatus\n");
if ([theEvent data1] == targetWindow)
{
! targetMask = [theEvent data2];
! [self _setCursor];
}
break;
--- 696,708 ----
NSDebugLLog(@"NSDragging", @"got GSAppKitDraggingStatus\n");
if ([theEvent data1] == targetWindow)
{
! int newTargetMask = [theEvent data2];
! if (newTargetMask != targetMask)
! {
! targetMask = newTargetMask;
! [self _setCursor];
! }
}
break;
***************
*** 785,791 ****
dragWindow = nil;
}
! // If we have are not hovering above a window that we controll
// we are dragging to an external application.
dragExternal = (mouseWindow != (Window) None) && (dragWindow == nil);
--- 789,795 ----
dragWindow = nil;
}
! // If we have are not hovering above a window that we own
// we are dragging to an external application.
dragExternal = (mouseWindow != (Window) None) && (dragWindow == nil);
Index: Source/SharedX/XGGeneric.h
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/xgps/Source/SharedX/XGGeneric.h,v
retrieving revision 1.14
diff -c -r1.14 XGGeneric.h
*** Source/SharedX/XGGeneric.h 7 Dec 2001 04:03:11 -0000 1.14
--- Source/SharedX/XGGeneric.h 16 Dec 2001 20:19:59 -0000
***************
*** 62,68 ****
long currentFocusWindow;
long desiredFocusWindow;
long focusRequestNumber;
- Window currentMouseWindow;
unsigned char lMouse;
unsigned char mMouse;
unsigned char rMouse;
--- 62,67 ----