--- orig/ChangeLog
+++ mod/ChangeLog
@@ -2,6 +2,48 @@
 # arch-tag: automatic-ChangeLog--richwareham@users.sourceforge.net--DesktopManager/DesktopManager--dev--0.5
 #
 
+2004-07-15 13:19:05 GMT	Rich Wareham <richwareham@users.sourceforge.net>	patch-97
+
+    Summary:
+      Added possibility of having Tab as hotkey
+    Revision:
+      DesktopManager--dev--0.5--patch-97
+
+    Added the possibility of Tab as a hot key. Unfortunately we can't capture Ctrl-Tab in the keyDown messages so we can't set it via preferences. Manual editting of prefs file should work however.
+
+    modified files:
+     ChangeLog DesktopManager.xcode/rjw57.pbxuser HotKeys/HotKey.m
+     Utility/MouseWatcher.m
+
+
+2004-07-15 12:32:35 GMT	Rich Wareham <richwareham@users.sourceforge.net>	patch-96
+
+    Summary:
+      Move windows between desktops via pager
+    Revision:
+      DesktopManager--dev--0.5--patch-96
+
+    Can now drag windows between desktops using the desktop pager.
+    
+    Based on main patch by Naveen Michaud-Agrawal <infinite8s@yahoo.com>
+    
+    Modified by Ka-Hing Cheung <kahing@gmail.com> to only cause desktop switch on mouse up.
+    Modified by me to tidy up warnings / make cmore consistent with DM coding style.
+
+    modified files:
+     ChangeLog Core/ForeignWindow.m Core/WorkspaceController.m
+     DesktopManager.xcode/rjw57.pbxuser Include/ForeignWindow.h
+     Include/WindowControllerEvents.h Include/WorkspaceController.h
+     Plugins/DesktopPager/DesktopPagerCell.h
+     Plugins/DesktopPager/DesktopPagerCell.m
+     Plugins/DesktopPager/DesktopPagerView.m
+     Plugins/DockExtension/ControllerEventHandlers.c
+     Plugins/DockExtension/ControllerEventHandlers.h
+     Plugins/DockExtension/WindowController.c
+     Plugins/DockExtension/WindowController.h
+     Plugins/DockExtension/main.c
+
+
 2004-07-12 16:09:15 GMT	Rich Wareham <richwareham@users.sourceforge.net>	patch-95
 
     Summary:


--- orig/Core/ForeignWindow.m
+++ mod/Core/ForeignWindow.m
@@ -335,6 +335,24 @@
     sendEvent(&theEvent);
 }
 
+- (void) hide {
+    AppleEvent theEvent;
+    
+    makeEvent(kWindowControllerHideWindow, &theEvent);
+    addIntParm(wid, 'wid ', &theEvent);
+    
+    sendEvent(&theEvent);
+}
+
+- (void) show {
+    AppleEvent theEvent;
+    
+    makeEvent(kWindowControllerShowWindow, &theEvent);
+    addIntParm(wid, 'wid ', &theEvent);
+    
+    sendEvent(&theEvent);
+}
+
 - (void) fade {
     AppleEvent theEvent;
     


--- orig/Core/WorkspaceController.m
+++ mod/Core/WorkspaceController.m
@@ -474,18 +474,16 @@
 }
 
 - (ForeignWindow*) windowContainingPoint: (NSPoint) mouseLoc {
+	return [self windowContainingPoint: mouseLoc inWorkspace: [self currentWorkspace]];
+}
 
-	
-	// NSLog(@"Mouse at (%f,%f)", mouseLoc.x, mouseLoc.y);
-	
+- (ForeignWindow*) windowContainingPoint: (NSPoint) mouseLoc inWorkspace: (Workspace*) ws {
 	// Start walking trough the window list from top to bottom
 	// and return if we find a window.
-	int i=0; NSArray *windowList = [[self currentWorkspace] windowList];
+	int i=0; NSArray *windowList = [ws windowList];
 	for(i=0; i<[windowList count]; i++) {
 		ForeignWindow *window = (ForeignWindow*) [windowList objectAtIndex: i];
 		NSRect screenRect = [window screenRect];
-		//NSLog(@"(%f,%f) +(%f,%f) - %@", screenRect.origin.x, screenRect.origin.y,
-	    //		screenRect.size.width, screenRect.size.height, [window title]);
 		
 		if(NSMouseInRect(mouseLoc, screenRect, NO)) {
 			return window;


--- orig/HotKeys/HotKey.m
+++ mod/HotKeys/HotKey.m
@@ -254,7 +254,7 @@
 			return C2S(0x2196);
 			break;
 		case kSpaceCharCode:
-			return @"<Spc>";
+			return @"Space";
 			break;
 		case kReturnCharCode:
 			return C2S(0x23CE);
@@ -262,6 +262,9 @@
 		case kEscapeCharCode:
 			return C2S(0x238B);
 			break;	
+		case kTabCharCode:
+			return @"Tab";
+			break;
 	}
 	
 	// NSLog(@"CharCode: %i", charCode);


--- orig/Include/ForeignWindow.h
+++ mod/Include/ForeignWindow.h
@@ -42,6 +42,8 @@
 - (int) workspaceNumber;
 - (CGSWindow) windowNumber;
 - (ForeignWindow*) movementParent;
+- (void) show;
+- (void) hide;
 - (void) fade;
 - (void) unFade;
 - (void) move: (NSPoint) to;
@@ -59,5 +61,6 @@
 - (int) tags;
 - (uint32_t) eventMask;
 - (void) setEventMask: (uint32_t) mask;
+- (void) moveToWorkspaceRepresentedBy: (id) represent;
 
 @end


--- orig/Include/WindowControllerEvents.h
+++ mod/Include/WindowControllerEvents.h
@@ -23,6 +23,8 @@
 };
 
 enum {
+	kWindowControllerHideWindow		= 'hidw',
+	kWindowControllerShowWindow		= 'show',
     kWindowControllerFadeWindow 	= 'fdwn',
     kWindowControllerUnFadeWindow 	= 'ufdw',
     kWindowControllerMoveWindow		= 'mvwn',


--- orig/Include/WorkspaceController.h
+++ mod/Include/WorkspaceController.h
@@ -51,6 +51,7 @@
 - (int) currentWorkspaceIndex;
 - (NSArray*) workspaceNames;
 - (ForeignWindow*) windowContainingPoint: (NSPoint) screenPoint;
+- (ForeignWindow*) windowContainingPoint: (NSPoint) screenPoint inWorkspace: (Workspace*) ws;
 - (ForeignWindow*) windowUnderPointer;
 - (void) collectWindows;
 


--- orig/Plugins/DesktopPager/DesktopPagerCell.h
+++ mod/Plugins/DesktopPager/DesktopPagerCell.h
@@ -25,10 +25,13 @@
 	BOOL dragging;
 	ForeignWindow *draggingWindow;
 	NSPoint delta;
+
+	/* These are for dragging windows between workspaces */
+	Workspace* dragInWorkspace, *dragToWorkspace;
 }
 
 - (void) setTargetHeight: (int) height;
 - (int) targetHeight;
-
+- (DesktopPagerCell *) pointToCell:(NSView *)controlView point:(NSPoint)point;
 
 @end


--- orig/Plugins/DesktopPager/DesktopPagerCell.m
+++ mod/Plugins/DesktopPager/DesktopPagerCell.m
@@ -26,6 +26,7 @@
 	id mySelf = [super init];
 	if(mySelf) {
 		targetHeight = 50;
+//        [self sendActionOn: (NSLeftMouseUpMask | NSLeftMouseDraggedMask)];
 	}
 	return mySelf;
 }
@@ -198,47 +199,97 @@
 	Workspace *ws = [self representedObject];
 	
 	if(!ws) { return NO; }
+    
+    DesktopPagerCell *tmp = [self pointToCell: controlView point: startPoint];
+		
+	startPoint = [tmp cellPointToScreenPoint: startPoint cellFrame: lastCellFrame];
+	draggingWindow = [wsController windowContainingPoint: startPoint inWorkspace: ws];
 	
-	if(ws && ![ws isSelected]) { [ws selectWithDefaultTransition]; }
-	
-	startPoint = [self cellPointToScreenPoint: startPoint cellFrame: lastCellFrame];
-	draggingWindow = [wsController windowContainingPoint: startPoint];
-	
-	if(!draggingWindow) { return nil; }
+	if(!draggingWindow) { 
+        if(![ws isSelected]) { [ws selectWithDefaultTransition]; }
+        return nil;
+    }
 	
 	delta.x = [draggingWindow screenRect].origin.x - startPoint.x;
 	delta.y = [draggingWindow screenRect].origin.y - startPoint.y;
 	[draggingWindow retain];
-	dragging = YES;
+    
+	dragInWorkspace = dragToWorkspace = [tmp representedObject];
 	
 	return YES;
 }
 
 - (BOOL)continueTracking:(NSPoint)lastPoint at:(NSPoint)currentPoint inView:(NSView*)controlView {
-	if(!dragging) { return NO; }
+	if(!draggingWindow) { return NO; }
+    dragging = YES;	
 	
-	if(!NSPointInRect(currentPoint, lastCellFrame)) {
+	if (!NSPointInRect(currentPoint, [controlView bounds])) {
 		// Don't move windows out of the screen but
 		// keep tracking...
 		return YES;
 	}
+
+    int row, column;
+	NSMatrix *mControlView = (NSMatrix*) controlView;
+	BOOL inControlView = [mControlView getRow: &row column:&column forPoint: currentPoint];
+    if(!inControlView) {
+		return NO;
+	}
 	
-	currentPoint = [self cellPointToScreenPoint: currentPoint cellFrame: lastCellFrame];
-	
+    id cell = [mControlView cellAtRow: row column: column];
+    dragToWorkspace = [cell representedObject];
+
+	if ([dragToWorkspace workspaceNumber] != [dragInWorkspace workspaceNumber]) {
+		// We've moved to a new workspace
+		[draggingWindow hide];
+		[draggingWindow moveToWorkspaceRepresentedBy: cell];
+		[dragInWorkspace updateWindowList];
+		[dragToWorkspace updateWindowList];
+	}
+		
+	// Move window to new coordinates
+	currentPoint = [cell cellPointToScreenPoint: currentPoint cellFrame: [mControlView cellFrameAtRow:row column:column]];		
+
 	NSPoint newPoint;
 	newPoint.x = currentPoint.x + delta.x;
 	newPoint.y = currentPoint.y + delta.y;
-	
 	[draggingWindow move: newPoint];
+	
+	if ([dragToWorkspace workspaceNumber] != [dragInWorkspace workspaceNumber]) {
+		[draggingWindow show];
+		[draggingWindow focusOwner];
+		//[dragToWorkspace selectWithDefaultTransition];
+		dragInWorkspace = dragToWorkspace;
+	}
+
 	[[self controlView] setNeedsDisplay: YES];
 	
 	return YES;
 }
 
 - (void)stopTracking:(NSPoint)lastPoint at:(NSPoint)stopPoint inView:(NSView *)controlView mouseIsUp:(BOOL)flag {
+    if(!dragging) {
+        // if we are not dragging, and this is mouse up, switch workspace
+        Workspace *ws = [[self pointToCell: controlView point: lastPoint] representedObject];
+        
+        if(ws && ![ws isSelected]) { [ws selectWithDefaultTransition]; }
+    }
 	dragging = NO;
 	
 	[draggingWindow release];
+    draggingWindow = nil;
+}
+
+- (DesktopPagerCell *) pointToCell:(NSView *)controlView point:(NSPoint)point {
+    int row, column;
+    BOOL inControlView = [(NSMatrix*) controlView getRow: &row column:&column forPoint: point];
+    if(!inControlView) {
+		return nil;
+	}
+	
+    id cell = [(NSMatrix*) controlView cellAtRow: row column: column];
+    
+    return cell;
 }
 
 + (BOOL)prefersTrackingUntilMouseUp { return YES; }


--- orig/Plugins/DesktopPager/DesktopPagerView.m
+++ mod/Plugins/DesktopPager/DesktopPagerView.m
@@ -82,7 +82,7 @@
             name: NOTIFICATION_WINDOWLAYOUTUPDATED
             object: nil
         ];
-						
+
 		[self readPreferences];
     }
 


--- orig/Plugins/DockExtension/ControllerEventHandlers.c
+++ mod/Plugins/DockExtension/ControllerEventHandlers.c
@@ -97,7 +97,29 @@
 
 /* These are the various AppleEvent handlers, they are used to
  * translate the events into calls to functions in WindowManipulation.c */
- 
+
+/* Hide a window */
+OSErr hideWindowHandler( const AppleEvent *theEvent,
+    AppleEvent *reply, SInt32 handlerRefcon) {
+    int wid;
+    
+    wid = getIntParam(theEvent, 'wid ');
+    hideWindow(wid);
+    
+    return 0;
+}
+
+/* Show a window */
+OSErr showWindowHandler( const AppleEvent *theEvent,
+    AppleEvent *reply, SInt32 handlerRefcon) {
+    int wid;
+    
+    wid = getIntParam(theEvent, 'wid ');
+    showWindow(wid);
+    
+    return 0;
+}
+
 /* Fade a window */
 OSErr fadeWindowHandler( const AppleEvent *theEvent,
     AppleEvent *reply, SInt32 handlerRefcon) {


--- orig/Plugins/DockExtension/ControllerEventHandlers.h
+++ mod/Plugins/DockExtension/ControllerEventHandlers.h
@@ -18,6 +18,10 @@
 
 #include <Carbon/Carbon.h>
 
+OSErr hideWindowHandler( const AppleEvent *theEvent,
+    AppleEvent *reply, SInt32 handlerRefcon);
+OSErr showWindowHandler( const AppleEvent *theEvent,
+    AppleEvent *reply, SInt32 handlerRefcon);
 OSErr fadeWindowHandler( const AppleEvent *theEvent,
     AppleEvent *reply, SInt32 handlerRefcon);
 OSErr unFadeWindowHandler( const AppleEvent *theEvent,


--- orig/Plugins/DockExtension/WindowController.c
+++ mod/Plugins/DockExtension/WindowController.c
@@ -22,6 +22,20 @@
 #include <unistd.h>
 #include <syslog.h>
 
+void hideWindow(int wid) {
+	CGSConnection cid;
+	
+	cid = _CGSDefaultConnection();
+	CGSSetWindowAlpha(cid, wid, 0.0);
+}
+
+void showWindow(int wid) {
+	CGSConnection cid;
+	
+	cid = _CGSDefaultConnection();
+	CGSSetWindowAlpha(cid, wid, 1.0);
+}
+
 void fadeWindow(int wid) {
 	float alpha = 0;
     CGSConnection cid;
@@ -57,7 +71,6 @@
     CGSConnection cid;
     CGPoint point;
 	CGSValue group = NULL;
-	int groupNo = 0;
 	
     cid = _CGSDefaultConnection();
     point.x = x; point.y = y;
@@ -68,6 +81,7 @@
 	
 	if(group) {
 		// CGSMoveWindowWithGroup(cid, wid, &point, groupNo);
+		//CGSMoveWindowWithGroup(cid, wid, &point, groupNo);
 	} else {
 		CGSMoveWindow(cid, wid, &point);
 	}


--- orig/Plugins/DockExtension/WindowController.h
+++ mod/Plugins/DockExtension/WindowController.h
@@ -18,6 +18,8 @@
  
 #include <Carbon/Carbon.h>
 
+void hideWindow(int wid);
+void showWindow(int wid);
 void fadeWindow(int wid);
 void unFadeWindow(int wid);
 void moveWindow(int wid, float x, float y);


--- orig/Plugins/DockExtension/main.c
+++ mod/Plugins/DockExtension/main.c
@@ -53,6 +53,22 @@
     /* Install event handlers */
     err = AEInstallEventHandler(
         kWindowControllerClass,
+        kWindowControllerHideWindow,
+        NewAEEventHandlerUPP((&hideWindowHandler) + offset),
+        0, FALSE
+    );
+    if(err) { syslog(LOG_ERR, "Error registering hide handler: %i", err); }
+
+    err = AEInstallEventHandler(
+        kWindowControllerClass,
+        kWindowControllerShowWindow,
+        NewAEEventHandlerUPP((&showWindowHandler) + offset),
+        0, FALSE
+    );
+    if(err) { syslog(LOG_ERR, "Error registering show handler: %i", err); }
+
+    err = AEInstallEventHandler(
+        kWindowControllerClass,
         kWindowControllerFadeWindow,
         NewAEEventHandlerUPP((&fadeWindowHandler) + offset),
         0, FALSE


--- orig/Utility/MouseWatcher.m
+++ mod/Utility/MouseWatcher.m
@@ -51,17 +51,23 @@
 }
 
 - (MouseWatcherEdge) _edgeContainingPoint: (CGPoint) loc {
-	if((loc.x >= screenRect.origin.x) && (loc.x <= screenRect.origin.x + 3)) {
-		return LeftEdge;
-	}
-	if((loc.x <= screenRect.origin.x + screenRect.size.width) && 
-	   (loc.x >= screenRect.origin.x + screenRect.size.width - 3)) {
-		return RightEdge;
-	}
-	if((loc.y <= screenRect.origin.y + screenRect.size.height) && 
-	   (loc.y >= screenRect.origin.y + screenRect.size.height - 3)) {
-		return BottomEdge;
-	}
+    if((loc.y >= screenRect.origin.y + 10) &&
+       (loc.y <= screenRect.origin.y + screenRect.size.height - 10)) {
+        if((loc.x >= screenRect.origin.x) && (loc.x <= screenRect.origin.x + 3)) {
+            return LeftEdge;
+        }
+        if((loc.x <= screenRect.origin.x + screenRect.size.width) && 
+           (loc.x >= screenRect.origin.x + screenRect.size.width - 3)) {
+            return RightEdge;
+        }
+    }
+    if((loc.x >= screenRect.origin.x + 10) &&
+       (loc.x <= screenRect.origin.x + screenRect.size.width - 10)) {
+        if((loc.y <= screenRect.origin.y + screenRect.size.height) && 
+           (loc.y >= screenRect.origin.y + screenRect.size.height - 3)) {
+            return BottomEdge;
+        }
+    }
 	
 	return None;
 }



