Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Eagar <joeedh@gmail.com>2009-11-02 09:33:16 +0300
committerJoseph Eagar <joeedh@gmail.com>2009-11-02 09:33:16 +0300
commite3a410d224380a82099cfd7e9f47074293df001b (patch)
tree7054dac876ffe8cb33cce426696c3b5373842608 /intern/ghost
parent71d2ceb69147aeead0800cb3b66c37fd132e8c48 (diff)
shapekeys are now stored as customdata in editmode, so edit operations like subdivide work (mostly) correctly. tesselated faces now store correct normals in more situations. and added more missing files from the last merge, there may be more though.
Diffstat (limited to 'intern/ghost')
-rw-r--r--intern/ghost/GHOST_C-api.h6
-rw-r--r--intern/ghost/GHOST_IWindow.h2
-rw-r--r--intern/ghost/GHOST_Rect.h21
-rw-r--r--intern/ghost/GHOST_Types.h6
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp14
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.h34
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm222
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp43
-rw-r--r--intern/ghost/intern/GHOST_Window.cpp27
-rw-r--r--intern/ghost/intern/GHOST_Window.h69
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.h16
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.mm148
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp57
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.h5
14 files changed, 360 insertions, 310 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 00d2cdb1e3b..bd812177f17 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -372,11 +372,13 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
* events when the mouse is outside the window. X11 only, others
* do this automatically.
* @param windowhandle The handle to the window
- * @param grab The new grab state of the cursor.
+ * @param mode The new grab state of the cursor.
+ * @param bounds The grab ragion (optional) - left,top,right,bottom
* @return Indication of success.
*/
extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
- int grab, int warp, int restore);
+ GHOST_TGrabCursorMode mode,
+ int* bounds);
/***************************************************************************************
** Access to mouse button and keyboard states.
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index 993b41a4d4f..512fad877cb 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -271,7 +271,7 @@ public:
* @param grab The new grab state of the cursor.
* @return Indication of success.
*/
- virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp, bool restore) { return GHOST_kSuccess; };
+ virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds) { return GHOST_kSuccess; };
};
diff --git a/intern/ghost/GHOST_Rect.h b/intern/ghost/GHOST_Rect.h
index 6271ecad408..6a29b1ffc26 100644
--- a/intern/ghost/GHOST_Rect.h
+++ b/intern/ghost/GHOST_Rect.h
@@ -127,6 +127,13 @@ public:
virtual inline void unionPoint(GHOST_TInt32 x, GHOST_TInt32 y);
/**
+ * Grows the rectangle to included a point.
+ * @param x The x-coordinate of the point.
+ * @param y The y-coordinate of the point.
+ */
+ virtual inline void wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 ofs);
+
+ /**
* Returns whether the point is inside this rectangle.
* Point on the boundary is considered inside.
* @param x x-coordinate of point to test.
@@ -221,6 +228,20 @@ inline void GHOST_Rect::unionPoint(GHOST_TInt32 x, GHOST_TInt32 y)
if (y < m_t) m_t = y;
if (y > m_b) m_b = y;
}
+#include <stdio.h>
+inline void GHOST_Rect::wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 ofs)
+{
+ GHOST_TInt32 w= getWidth();
+ GHOST_TInt32 h= getHeight();
+
+ /* highly unlikely but avoid eternal loop */
+ if(w-ofs*2 <= 0 || h-ofs*2 <= 0)
+ return;
+ while(x-ofs < m_l) x+= w-(ofs*2);
+ while(y-ofs < m_t) y+= h-(ofs*2);
+ while(x+ofs > m_r) x-= w-(ofs*2);
+ while(y+ofs > m_b) y-= h-(ofs*2);
+}
inline bool GHOST_Rect::isInside(GHOST_TInt32 x, GHOST_TInt32 y) const
{
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 14e3c4bb5f7..e98e58740ad 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -341,6 +341,12 @@ typedef enum {
GHOST_kKeyF24
} GHOST_TKey;
+typedef enum {
+ GHOST_kGrabDisable = 0, /* grab not set */
+ GHOST_kGrabNormal, /* no cursor adjustments */
+ GHOST_kGrabWrap, /* wrap the mouse location to prevent limiting screen bounds */
+ GHOST_kGrabHide, /* hide the mouse while grabbing and restore the original location on release (numbuts) */
+} GHOST_TGrabCursorMode;
typedef void* GHOST_TEventDataPtr;
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index e225ad4fd90..0160df552cc 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -355,11 +355,21 @@ GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
- int grab, int warp, int restore)
+ GHOST_TGrabCursorMode mode,
+ int *bounds)
{
GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+ GHOST_Rect bounds_rect, bounds_win;
+
+ if(bounds) {
+ /* if this is X11 specific we need a function that converts */
+ window->getClientBounds(bounds_win);
+ window->clientToScreen(bounds[0], bounds_win.getHeight() - bounds[1], bounds_rect.m_l, bounds_rect.m_t);
+ window->clientToScreen(bounds[2], bounds_win.getHeight() - bounds[3], bounds_rect.m_r, bounds_rect.m_b);
+
+ }
- return window->setCursorGrab(grab?true:false, warp?true:false, restore?true:false);
+ return window->setCursorGrab(mode, bounds ? &bounds_rect:NULL);
}
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
index 002089e4185..709625c5bef 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -228,34 +228,7 @@ protected:
* @return Indication whether the event was handled.
*/
GHOST_TSuccess handleKeyEvent(void *eventPtr);
-
- /**
- * Handles all basic Mac application stuff for a mouse down event.
- * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
- * @return Indication whether the event was handled.
- */
- // bool handleMouseDown(void *eventPtr);
-
- /**
- * Handles a Mac menu command.
- * @param menuResult A Mac menu/item identifier.
- * @return Indication whether the event was handled.
- */
- // bool handleMenuCommand(GHOST_TInt32 menuResult);
- /* callback for blender generated events */
-// static OSStatus blendEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData);
-
-
- /**
- * Callback for Mac Timer tasks that expire.
- * @param tmTask Pointer to the timer task that expired.
- */
- //static void s_timerCallback(TMTaskPtr tmTask);
-
- /** Event handler reference. */
- //EventHandlerRef m_handler;
-
/** Start time at initialization. */
GHOST_TUns64 m_start_time;
@@ -266,7 +239,12 @@ protected:
GHOST_TUns32 m_modifierMask;
/** Ignores window size messages (when window is dragged). */
- bool m_ignoreWindowSizedMessages;
+ bool m_ignoreWindowSizedMessages;
+
+ /** Stores the mouse cursor delta due to setting a new cursor position
+ * Needed because cocoa event delta cursor move takes setCursorPosition changes too.
+ */
+ GHOST_TInt32 m_cursorDelta_x, m_cursorDelta_y;
};
#endif // _GHOST_SYSTEM_COCOA_H_
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index b924adeebde..b476ee8f0f2 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -525,7 +525,8 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) {
@interface CocoaAppDelegate : NSObject {
GHOST_SystemCocoa *systemCocoa;
}
--(void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa;
+- (void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa;
+- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
- (void)applicationWillTerminate:(NSNotification *)aNotification;
@end
@@ -536,6 +537,12 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) {
systemCocoa = sysCocoa;
}
+- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
+{
+ NSLog(@"\nGet open file event from cocoa : %@",filename);
+ return YES;
+}
+
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
//TODO: implement graceful termination through Cocoa mechanism to avoid session log off to be cancelled
@@ -565,6 +572,8 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
{
m_modifierMask =0;
m_pressedMouseButtons =0;
+ m_cursorDelta_x=0;
+ m_cursorDelta_y=0;
m_displayManager = new GHOST_DisplayManagerCocoa ();
GHOST_ASSERT(m_displayManager, "GHOST_SystemCocoa::GHOST_SystemCocoa(): m_displayManager==0\n");
m_displayManager->initialize();
@@ -656,13 +665,14 @@ GHOST_TSuccess GHOST_SystemCocoa::init()
[NSApp setWindowsMenu:windowMenu];
[windowMenu release];
}
- [NSApp finishLaunching];
}
if ([NSApp delegate] == nil) {
CocoaAppDelegate *appDelegate = [[CocoaAppDelegate alloc] init];
[appDelegate setSystemCocoa:this];
[NSApp setDelegate:appDelegate];
}
+
+ [NSApp finishLaunching];
[pool drain];
}
@@ -787,7 +797,9 @@ GHOST_TSuccess GHOST_SystemCocoa::endFullScreen(void)
-
+/**
+ * @note : returns coordinates in Cocoa screen coordinates
+ */
GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const
{
NSPoint mouseLoc = [NSEvent mouseLocation];
@@ -798,18 +810,25 @@ GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt3
return GHOST_kSuccess;
}
-
+/**
+ * @note : expect Cocoa screen coordinates
+ */
GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) const
{
float xf=(float)x, yf=(float)y;
+ GHOST_WindowCocoa* window = (GHOST_WindowCocoa*)m_windowManager->getActiveWindow();
+ NSScreen *windowScreen = window->getScreen();
+ NSRect screenRect = [windowScreen frame];
+ //Set position relative to current screen
+ xf -= screenRect.origin.x;
+ yf -= screenRect.origin.y;
+
//Quartz Display Services uses the old coordinates (top left origin)
- yf = [[NSScreen mainScreen] frame].size.height -yf;
-
- //CGAssociateMouseAndMouseCursorPosition(false);
- CGWarpMouseCursorPosition(CGPointMake(xf, yf));
- //CGAssociateMouseAndMouseCursorPosition(true);
+ yf = screenRect.size.height -yf;
+ CGDisplayMoveCursorToPoint([[[windowScreen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue], CGPointMake(xf, yf));
+
return GHOST_kSuccess;
}
@@ -873,15 +892,6 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
if (timerMgr->fireTimers(getMilliSeconds())) {
anyProcessed = true;
- }
-
- if (getFullScreen()) {
- // Check if the full-screen window is dirty
- GHOST_IWindow* window = m_windowManager->getFullScreenWindow();
- if (((GHOST_WindowCarbon*)window)->getFullScreenDirty()) {
- pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) );
- anyProcessed = true;
- }
}*/
do {
@@ -999,6 +1009,12 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType,
GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest()
{
+ GHOST_Window* window = (GHOST_Window*)m_windowManager->getActiveWindow();
+
+ //Discard quit event if we are in cursor grab sequence
+ if (window && (window->getCursorGrabMode() != GHOST_kGrabDisable) && (window->getCursorGrabMode() != GHOST_kGrabNormal))
+ return GHOST_kExitCancel;
+
//Check open windows if some changes are not saved
if (m_windowManager->getAnyModifiedState())
{
@@ -1008,7 +1024,14 @@ GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest()
{
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) );
return GHOST_kExitNow;
+ } else {
+ //Give back focus to the blender window if user selected cancel quit
+ NSArray *windowsList = [NSApp orderedWindows];
+ if ([windowsList count]) {
+ [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil];
+ }
}
+
}
else {
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) );
@@ -1023,11 +1046,14 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventT
{
NSEvent *event = (NSEvent *)eventPtr;
GHOST_IWindow* window = m_windowManager->getActiveWindow();
+
+ if (!window) return GHOST_kFailure;
+
GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData();
switch (eventType) {
case NSTabletPoint:
- ct.Pressure = [event tangentialPressure];
+ ct.Pressure = [event pressure];
ct.Xtilt = [event tilt].x;
ct.Ytilt = [event tilt].y;
break;
@@ -1129,27 +1155,78 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
//No tablet event included : do nothing
break;
}
+
case NSMouseMoved:
- {
- if(window->getCursorWarp()) {
- GHOST_TInt32 x_warp, y_warp, x_accum, y_accum;
-
- window->getCursorWarpPos(x_warp, y_warp);
-
- window->getCursorWarpAccum(x_accum, y_accum);
- x_accum += [event deltaX];
- y_accum += -[event deltaY]; //Strange Apple implementation (inverted coordinates for the deltaY) ...
- window->setCursorWarpAccum(x_accum, y_accum);
-
- pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, x_warp+x_accum, y_warp+y_accum));
- }
- else { //Normal cursor operation: send mouse position in window
- NSPoint mousePos = [event locationInWindow];
- pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, mousePos.x, mousePos.y));
- window->setCursorWarpAccum(0, 0); //Mouse motion occured between two cursor warps, so we can reset the delta counter
+ switch (window->getCursorGrabMode()) {
+ case GHOST_kGrabHide: //Cursor hidden grab operation : no cursor move
+ {
+ GHOST_TInt32 x_warp, y_warp, x_accum, y_accum;
+
+ window->getCursorGrabInitPos(x_warp, y_warp);
+
+ window->getCursorGrabAccum(x_accum, y_accum);
+ x_accum += [event deltaX];
+ y_accum += -[event deltaY]; //Strange Apple implementation (inverted coordinates for the deltaY) ...
+ window->setCursorGrabAccum(x_accum, y_accum);
+
+ pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, x_warp+x_accum, y_warp+y_accum));
+ }
+ break;
+ case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries
+ {
+ NSPoint mousePos = [event locationInWindow];
+ GHOST_TInt32 x_mouse= mousePos.x;
+ GHOST_TInt32 y_mouse= mousePos.y;
+ GHOST_TInt32 x_accum, y_accum, x_cur, y_cur;
+ GHOST_Rect bounds, windowBounds, correctedBounds;
+
+ /* fallback to window bounds */
+ if(window->getCursorGrabBounds(bounds)==GHOST_kFailure)
+ window->getClientBounds(bounds);
+
+ //Switch back to Cocoa coordinates orientation (y=0 at botton,the same as blender internal btw!), and to client coordinates
+ window->getClientBounds(windowBounds);
+ window->screenToClient(bounds.m_l,bounds.m_b, correctedBounds.m_l, correctedBounds.m_t);
+ window->screenToClient(bounds.m_r, bounds.m_t, correctedBounds.m_r, correctedBounds.m_b);
+ correctedBounds.m_b = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_b;
+ correctedBounds.m_t = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_t;
+
+ //Update accumulation counts
+ window->getCursorGrabAccum(x_accum, y_accum);
+ x_accum += [event deltaX]-m_cursorDelta_x;
+ y_accum += -[event deltaY]-m_cursorDelta_y; //Strange Apple implementation (inverted coordinates for the deltaY) ...
+ window->setCursorGrabAccum(x_accum, y_accum);
+
+
+ //Warp mouse cursor if needed
+ x_mouse += [event deltaX]-m_cursorDelta_x;
+ y_mouse += -[event deltaY]-m_cursorDelta_y;
+ correctedBounds.wrapPoint(x_mouse, y_mouse, 2);
+
+ //Compensate for mouse moved event taking cursor position set into account
+ m_cursorDelta_x = x_mouse-mousePos.x;
+ m_cursorDelta_y = y_mouse-mousePos.y;
+
+ //Set new cursor position
+ window->clientToScreen(x_mouse, y_mouse, x_cur, y_cur);
+ setCursorPosition(x_cur, y_cur); /* wrap */
+
+ //Post event
+ window->getCursorGrabInitPos(x_cur, y_cur);
+ pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, x_cur + x_accum, y_cur + y_accum));
+ }
+ break;
+ default:
+ {
+ //Normal cursor operation: send mouse position in window
+ NSPoint mousePos = [event locationInWindow];
+ pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, mousePos.x, mousePos.y));
+ m_cursorDelta_x=0;
+ m_cursorDelta_y=0; //Mouse motion occured between two cursor warps, so we can reset the delta counter
+ }
+ break;
}
break;
- }
case NSScrollWheel:
{
@@ -1323,74 +1400,3 @@ void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const
[pool drain];
}
-
-#pragma mark Carbon stuff to remove
-
-#ifdef WITH_CARBON
-
-
-OSErr GHOST_SystemCarbon::sAEHandlerLaunch(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
-{
- //GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
-
- return noErr;
-}
-
-OSErr GHOST_SystemCarbon::sAEHandlerOpenDocs(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
-{
- //GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
- AEDescList docs;
- SInt32 ndocs;
- OSErr err;
-
- err = AEGetParamDesc(event, keyDirectObject, typeAEList, &docs);
- if (err != noErr) return err;
-
- err = AECountItems(&docs, &ndocs);
- if (err==noErr) {
- int i;
-
- for (i=0; i<ndocs; i++) {
- FSSpec fss;
- AEKeyword kwd;
- DescType actType;
- Size actSize;
-
- err = AEGetNthPtr(&docs, i+1, typeFSS, &kwd, &actType, &fss, sizeof(fss), &actSize);
- if (err!=noErr)
- break;
-
- if (i==0) {
- FSRef fsref;
-
- if (FSpMakeFSRef(&fss, &fsref)!=noErr)
- break;
- if (FSRefMakePath(&fsref, (UInt8*) g_firstFileBuf, sizeof(g_firstFileBuf))!=noErr)
- break;
-
- g_hasFirstFile = true;
- }
- }
- }
-
- AEDisposeDesc(&docs);
-
- return err;
-}
-
-OSErr GHOST_SystemCarbon::sAEHandlerPrintDocs(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
-{
- //GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
-
- return noErr;
-}
-
-OSErr GHOST_SystemCarbon::sAEHandlerQuit(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
-{
- GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
-
- sys->pushEvent( new GHOST_Event(sys->getMilliSeconds(), GHOST_kEventQuit, NULL) );
-
- return noErr;
-}
-#endif \ No newline at end of file
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 8c87abf16bc..ff4a5956a12 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -388,30 +388,37 @@ GHOST_SystemX11::processEvent(XEvent *xe)
{
XMotionEvent &xme = xe->xmotion;
- if(window->getCursorWarp()) {
- /* Calculate offscreen location and re-center the mouse */
- GHOST_TInt32 x_warp, y_warp, x_new, y_new, x_accum, y_accum;
-
- window->getCursorWarpPos(x_warp, y_warp);
- getCursorPosition(x_new, y_new);
-
- if(x_warp != x_new || y_warp != y_new) {
- window->getCursorWarpAccum(x_accum, y_accum);
- x_accum += x_new - x_warp;
- y_accum += y_new - y_warp;
-
- window->setCursorWarpAccum(x_accum, y_accum);
- setCursorPosition(x_warp, y_warp); /* reset */
-
+ if(window->getCursorGrabMode() != GHOST_kGrabDisable && window->getCursorGrabMode() != GHOST_kGrabNormal)
+ {
+ GHOST_TInt32 x_new= xme.x_root;
+ GHOST_TInt32 y_new= xme.y_root;
+ GHOST_TInt32 x_accum, y_accum;
+ GHOST_Rect bounds;
+
+ /* fallback to window bounds */
+ if(window->getCursorGrabBounds(bounds)==GHOST_kFailure)
+ window->getClientBounds(bounds);
+
+ /* could also clamp to screen bounds
+ * wrap with a window outside the view will fail atm */
+ bounds.wrapPoint(x_new, y_new, 2); /* offset of one incase blender is at screen bounds */
+ window->getCursorGrabAccum(x_accum, y_accum);
+
+ if(x_new != xme.x_root || y_new != xme.y_root) {
+ /* when wrapping we don't need to add an event because the
+ * setCursorPosition call will cause a new event after */
+ setCursorPosition(x_new, y_new); /* wrap */
+ window->setCursorGrabAccum(x_accum + (xme.x_root - x_new), y_accum + (xme.y_root - y_new));
+ }
+ else {
g_event = new
GHOST_EventCursor(
getMilliSeconds(),
GHOST_kEventCursorMove,
window,
- x_warp + x_accum,
- y_warp + y_accum
+ xme.x_root + x_accum,
+ xme.y_root + y_accum
);
-
}
}
else {
diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp
index 94feb83e003..33484284d7c 100644
--- a/intern/ghost/intern/GHOST_Window.cpp
+++ b/intern/ghost/intern/GHOST_Window.cpp
@@ -48,15 +48,14 @@ GHOST_Window::GHOST_Window(
:
m_drawingContextType(type),
m_cursorVisible(true),
- m_cursorGrabbed(false),
- m_cursorWarp(false),
+ m_cursorGrab(GHOST_kGrabDisable),
m_cursorShape(GHOST_kStandardCursorDefault),
m_stereoVisual(stereoVisual)
{
m_isUnsavedChanges = false;
- m_cursorWarpAccumPos[0] = 0;
- m_cursorWarpAccumPos[1] = 0;
+ m_cursorGrabAccumPos[0] = 0;
+ m_cursorGrabAccumPos[1] = 0;
m_fullScreen = state == GHOST_kWindowStateFullScreen;
if (m_fullScreen) {
@@ -98,13 +97,19 @@ GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible)
}
}
-GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab, bool warp, bool restore)
+GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds)
{
- if(m_cursorGrabbed == grab)
+ if(m_cursorGrab == mode)
return GHOST_kSuccess;
- if (setWindowCursorGrab(grab, warp, restore)) {
- m_cursorGrabbed = grab;
+ if (setWindowCursorGrab(mode)) {
+
+ if(mode==GHOST_kGrabDisable)
+ m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1;
+ else if (bounds) {
+ m_cursorGrabBounds= *bounds;
+ }
+ m_cursorGrab = mode;
return GHOST_kSuccess;
}
else {
@@ -112,6 +117,12 @@ GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab, bool warp, bool restore)
}
}
+GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect& bounds)
+{
+ bounds= m_cursorGrabBounds;
+ return (bounds.m_l==-1 && bounds.m_r==-1) ? GHOST_kFailure : GHOST_kSuccess;
+}
+
GHOST_TSuccess GHOST_Window::setCursorShape(GHOST_TStandardCursor cursorShape)
{
if (setWindowCursorShape(cursorShape)) {
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index 786918716c5..86447a8623c 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -158,10 +158,10 @@ public:
* @return The visibility state of the cursor.
*/
inline virtual bool getCursorVisibility() const;
- inline virtual bool getCursorWarp() const;
- inline virtual bool getCursorWarpPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
- inline virtual bool getCursorWarpAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
- inline virtual bool setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y);
+ inline virtual GHOST_TGrabCursorMode getCursorGrabMode() const;
+ inline virtual void getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
+ inline virtual void getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
+ inline virtual void setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y);
/**
* Shows or hides the cursor.
@@ -172,10 +172,16 @@ public:
/**
* Sets the cursor grab.
- * @param grab The new grab state of the cursor.
+ * @param mode The new grab state of the cursor.
* @return Indication of success.
*/
- virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp, bool restore);
+ virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds);
+
+ /**
+ * Gets the cursor grab region, if unset the window is used.
+ * reset when grab is disabled.
+ */
+ virtual GHOST_TSuccess getCursorGrabBounds(GHOST_Rect& bounds);
/**
* Sets the window "modified" status, indicating unsaved changes
@@ -247,7 +253,7 @@ protected:
* Sets the cursor grab on the window using
* native window system calls.
*/
- virtual GHOST_TSuccess setWindowCursorGrab(bool grab, bool warp, bool restore) { return GHOST_kSuccess; };
+ virtual GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode) { return GHOST_kSuccess; };
/**
* Sets the cursor shape on the window using
@@ -274,16 +280,16 @@ protected:
bool m_cursorVisible;
/** The current grabbed state of the cursor */
- bool m_cursorGrabbed;
-
- /** The current warped state of the cursor */
- bool m_cursorWarp;
+ GHOST_TGrabCursorMode m_cursorGrab;
/** Initial grab location. */
- GHOST_TInt32 m_cursorWarpInitPos[2];
+ GHOST_TInt32 m_cursorGrabInitPos[2];
+
+ /** Accumulated offset from m_cursorGrabInitPos. */
+ GHOST_TInt32 m_cursorGrabAccumPos[2];
- /** Accumulated offset from m_cursorWarpInitPos. */
- GHOST_TInt32 m_cursorWarpAccumPos[2];
+ /** Wrap the cursor within this region. */
+ GHOST_Rect m_cursorGrabBounds;
/** The current shape of the cursor */
GHOST_TStandardCursor m_cursorShape;
@@ -317,40 +323,27 @@ inline bool GHOST_Window::getCursorVisibility() const
return m_cursorVisible;
}
-inline bool GHOST_Window::getCursorWarp() const
+inline GHOST_TGrabCursorMode GHOST_Window::getCursorGrabMode() const
{
- return m_cursorWarp;
+ return m_cursorGrab;
}
-inline bool GHOST_Window::getCursorWarpPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const
+inline void GHOST_Window::getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const
{
- if(m_cursorWarp==false)
- return GHOST_kFailure;
-
- x= m_cursorWarpInitPos[0];
- y= m_cursorWarpInitPos[1];
- return GHOST_kSuccess;
+ x = m_cursorGrabInitPos[0];
+ y = m_cursorGrabInitPos[1];
}
-inline bool GHOST_Window::getCursorWarpAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const
+inline void GHOST_Window::getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const
{
- if(m_cursorWarp==false)
- return GHOST_kFailure;
-
- x= m_cursorWarpAccumPos[0];
- y= m_cursorWarpAccumPos[1];
- return GHOST_kSuccess;
+ x= m_cursorGrabAccumPos[0];
+ y= m_cursorGrabAccumPos[1];
}
-inline bool GHOST_Window::setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y)
+inline void GHOST_Window::setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y)
{
- if(m_cursorWarp==false)
- return GHOST_kFailure;
-
- m_cursorWarpAccumPos[0]= x;
- m_cursorWarpAccumPos[1]= y;
-
- return GHOST_kSuccess;
+ m_cursorGrabAccumPos[0]= x;
+ m_cursorGrabAccumPos[1]= y;
}
inline GHOST_TStandardCursor GHOST_Window::getCursorShape() const
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h
index 4037ebafc64..c1fa147eee1 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.h
+++ b/intern/ghost/intern/GHOST_WindowCocoa.h
@@ -170,6 +170,12 @@ public:
virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
/**
+ * Gets the screen the window is displayed in
+ * @return The NSScreen object
+ */
+ NSScreen* getScreen();
+
+ /**
* Sets the state of the window (normal, minimized, maximized).
* @param state The state of the window.
* @return Indication of success.
@@ -237,17 +243,11 @@ protected:
virtual GHOST_TSuccess setWindowCursorVisibility(bool visible);
/**
- * Sets the cursor warp accumulator. Overriden for workaround due to Cocoa next event after cursor set giving delta values non zero
- */
- inline virtual bool setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y);
-
- /**
* Sets the cursor grab on the window using
* native window system calls.
- * @param warp Only used when grab is enabled, hides the mouse and allows gragging outside the screen.
*/
- virtual GHOST_TSuccess setWindowCursorGrab(bool grab, bool warp, bool restore);
-
+ virtual GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode);
+
/**
* Sets the cursor shape on the window using
* native window system calls.
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
index a2b146c1e33..aac12e80893 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.mm
+++ b/intern/ghost/intern/GHOST_WindowCocoa.mm
@@ -34,6 +34,10 @@
#include <Carbon/Carbon.h>
#endif
+/***** Multithreaded opengl code : uncomment for enabling
+#include <OpenGL/OpenGL.h>
+*/
+
#include "GHOST_WindowCocoa.h"
#include "GHOST_SystemCocoa.h"
#include "GHOST_Debug.h"
@@ -50,14 +54,27 @@ static NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] =
};
#pragma mark Cocoa window delegate object
-
+/* live resize ugly patch
+extern "C" {
+ struct bContext;
+ typedef struct bContext bContext;
+ bContext* ghostC;
+ extern int wm_window_timer(const bContext *C);
+ extern void wm_window_process_events(const bContext *C);
+ extern void wm_event_do_handlers(bContext *C);
+ extern void wm_event_do_notifiers(bContext *C);
+ extern void wm_draw_update(bContext *C);
+};*/
@interface CocoaWindowDelegate : NSObject
+#ifdef MAC_OS_X_VERSION_10_6
+<NSWindowDelegate>
+#endif
{
GHOST_SystemCocoa *systemCocoa;
GHOST_WindowCocoa *associatedWindow;
}
-- (void)setSystemAndWindowCocoa:(const GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa;
+- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa;
- (void)windowWillClose:(NSNotification *)notification;
- (void)windowDidBecomeKey:(NSNotification *)notification;
- (void)windowDidResignKey:(NSNotification *)notification;
@@ -97,7 +114,22 @@ static NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] =
- (void)windowDidResize:(NSNotification *)notification
{
- systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, associatedWindow);
+#ifdef MAC_OS_X_VERSION_10_6
+ //if (![[notification object] inLiveResize]) {
+ //Send event only once, at end of resize operation (when user has released mouse button)
+#endif
+ systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, associatedWindow);
+#ifdef MAC_OS_X_VERSION_10_6
+ //}
+#endif
+ /* Live resize ugly patch. Needed because live resize runs in a modal loop, not letting main loop run
+ if ([[notification object] inLiveResize]) {
+ systemCocoa->dispatchEvents();
+ wm_window_timer(ghostC);
+ wm_event_do_handlers(ghostC);
+ wm_event_do_notifiers(ghostC);
+ wm_draw_update(ghostC);
+ }*/
}
@end
@@ -107,8 +139,6 @@ static NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] =
{
}
--(BOOL)canBecomeKeyWindow;
-
@end
@implementation CocoaWindow
@@ -125,7 +155,6 @@ static NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] =
//We need to subclass it in order to give Cocoa the feeling key events are trapped
@interface CocoaOpenGLView : NSOpenGLView
{
-
}
@end
@implementation CocoaOpenGLView
@@ -173,6 +202,7 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
//Creates the window
NSRect rect;
+ NSSize minSize;
rect.origin.x = left;
rect.origin.y = top;
@@ -187,6 +217,11 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
return;
}
+ //Forbid to resize the window below the blender defined minimum one
+ minSize.width = 320;
+ minSize.height = 240;
+ [m_window setContentMinSize:minSize];
+
setTitle(title);
@@ -480,6 +515,13 @@ void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST
outY = screenCoord.y;
}
+
+NSScreen* GHOST_WindowCocoa::getScreen()
+{
+ return [m_window screen];
+}
+
+
/**
* @note Fullscreen switch is not actual fullscreen with display capture. As this capture removes all OS X window manager features.
* Instead, the menu bar and the dock are hidden, and the window is made borderless and enlarged.
@@ -515,6 +557,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
//Make window borderless and enlarge it
[m_window setStyleMask:NSBorderlessWindowMask];
[m_window setFrame:[[m_window screen] frame] display:YES];
+ [m_window makeFirstResponder:m_openGLView];
#else
//With 10.5, we need to create a new window to change its style to borderless
//Hide menu & dock if needed
@@ -572,6 +615,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
//Make window normal and resize it
[m_window setStyleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)];
[m_window setFrame:[[m_window screen] visibleFrame] display:YES];
+ [m_window makeFirstResponder:m_openGLView];
#else
//With 10.5, we need to create a new window to change its style to borderless
//Show menu & dock if needed
@@ -696,6 +740,10 @@ GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextTyp
NSOpenGLPixelFormat *pixelFormat;
NSOpenGLContext *tmpOpenGLContext;
+ /***** Multithreaded opengl code : uncomment for enabling
+ CGLContextObj cglCtx;
+ */
+
switch (type) {
case GHOST_kDrawingContextTypeOpenGL:
if (!getValid()) break;
@@ -708,6 +756,13 @@ GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextTyp
break;
}
+ //Switch openGL to multhreaded mode
+ /******* Multithreaded opengl code : uncomment for enabling
+ cglCtx = (CGLContextObj)[tmpOpenGLContext CGLContextObj];
+ if (CGLEnable(cglCtx, kCGLCEMPEngine) == kCGLNoError)
+ printf("\nSwitched openGL to multithreaded mode");
+ */
+
if (!s_firstOpenGLcontext) s_firstOpenGLcontext = tmpOpenGLContext;
#ifdef WAIT_FOR_VSYNC
/* wait for vsync, to avoid tearing artifacts */
@@ -849,73 +904,42 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible)
}
-//Override this method to provide set feature even if not in warp
-inline bool GHOST_WindowCocoa::setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y)
+GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
{
- m_cursorWarpAccumPos[0]= x;
- m_cursorWarpAccumPos[1]= y;
+ GHOST_TSuccess err = GHOST_kSuccess;
- return GHOST_kSuccess;
-}
-
-
-GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(bool grab, bool warp, bool restore)
-{
- if (grab)
+ if (mode != GHOST_kGrabDisable)
{
//No need to perform grab without warp as it is always on in OS X
- if(warp) {
+ if(mode != GHOST_kGrabNormal) {
GHOST_TInt32 x_old,y_old;
- m_cursorWarp= true;
m_systemCocoa->getCursorPosition(x_old,y_old);
- screenToClient(x_old, y_old, m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]);
+ screenToClient(x_old, y_old, m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
//Warp position is stored in client (window base) coordinates
- setWindowCursorVisibility(false);
- return CGAssociateMouseAndMouseCursorPosition(false) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
+ setCursorGrabAccum(0, 0);
+
+ if(mode == GHOST_kGrabHide) {
+ setWindowCursorVisibility(false);
+ }
+
+ //Dissociate cursor position even for warp mode, to allow mouse acceleration to work even when warping the cursor
+ err = CGAssociateMouseAndMouseCursorPosition(false) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
}
}
else {
- if(m_cursorWarp)
- {/* are we exiting warp */
+ if(m_cursorGrab==GHOST_kGrabHide)
+ {
+ //No need to set again cursor position, as it has not changed for Cocoa
setWindowCursorVisibility(true);
- /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
- if(restore) {
- GHOST_Rect bounds;
- GHOST_TInt32 x_new, y_new, x_cur, y_cur;
-
- getClientBounds(bounds);
- x_new= m_cursorWarpInitPos[0]+m_cursorWarpAccumPos[0];
- y_new= m_cursorWarpInitPos[1]+m_cursorWarpAccumPos[1];
-
- if(x_new < 0) x_new = 0;
- if(y_new < 0) y_new = 0;
- if(x_new > bounds.getWidth()) x_new = bounds.getWidth();
- if(y_new > bounds.getHeight()) y_new = bounds.getHeight();
-
- //get/set cursor position works in screen coordinates
- clientToScreen(x_new, y_new, x_cur, y_cur);
- m_systemCocoa->setCursorPosition(x_cur, y_cur);
-
- //As Cocoa will give as first deltaX,deltaY this change in cursor position, we need to compensate for it
- //Issue appearing in case of two transform operations conducted w/o mouse motion in between
- x_new=m_cursorWarpAccumPos[0];
- y_new=m_cursorWarpAccumPos[1];
- setCursorWarpAccum(-x_new, -y_new);
- }
- else {
- GHOST_TInt32 x_new, y_new;
- //get/set cursor position works in screen coordinates
- clientToScreen(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1], x_new, y_new);
- m_systemCocoa->setCursorPosition(x_new, y_new);
- setCursorWarpAccum(0, 0);
- }
-
- m_cursorWarp= false;
- return CGAssociateMouseAndMouseCursorPosition(true) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
}
+
+ err = CGAssociateMouseAndMouseCursorPosition(true) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
+ /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
+ setCursorGrabAccum(0, 0);
+ m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1; /* disable */
}
- return GHOST_kSuccess;
+ return err;
}
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape)
@@ -979,7 +1003,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap
samplesPerPixel:2
hasAlpha:YES
isPlanar:YES
- colorSpaceName:NSDeviceBlackColorSpace
+ colorSpaceName:NSDeviceWhiteColorSpace
bytesPerRow:(sizex/8 + (sizex%8 >0 ?1:0))
bitsPerPixel:1];
@@ -989,10 +1013,10 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap
for (y=0; y<nbUns16; y++) {
#if !defined(__LITTLE_ENDIAN__)
- cursorBitmap[y] = uns16ReverseBits((bitmap[2*y]<<0) | (bitmap[2*y+1]<<8));
+ cursorBitmap[y] = ~uns16ReverseBits((bitmap[2*y]<<0) | (bitmap[2*y+1]<<8));
cursorBitmap[nbUns16+y] = uns16ReverseBits((mask[2*y]<<0) | (mask[2*y+1]<<8));
#else
- cursorBitmap[y] = uns16ReverseBits((bitmap[2*y+1]<<0) | (bitmap[2*y]<<8));
+ cursorBitmap[y] = ~uns16ReverseBits((bitmap[2*y+1]<<0) | (bitmap[2*y]<<8));
cursorBitmap[nbUns16+y] = uns16ReverseBits((mask[2*y+1]<<0) | (mask[2*y]<<8));
#endif
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index d197b534352..d9c2654f446 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -297,11 +297,13 @@ GHOST_WindowX11(
// we want this window treated.
XSizeHints * xsizehints = XAllocSizeHints();
- xsizehints->flags = USPosition | USSize;
+ xsizehints->flags = PPosition | PSize | PMinSize;
xsizehints->x = left;
xsizehints->y = top;
xsizehints->width = width;
xsizehints->height = height;
+ xsizehints->min_width= 320; // size hints, could be made apart of the ghost api
+ xsizehints->min_height= 240; // limits are also arbitrary, but should not allow 1x1 window
XSetWMNormalHints(m_display, m_window, xsizehints);
XFree(xsizehints);
@@ -382,7 +384,6 @@ GHOST_WindowX11(
XSetWMHints(display, m_window, xwmhints );
XFree(xwmhints);
// done setting the icon
-
setTitle(title);
@@ -1400,47 +1401,35 @@ setWindowCursorVisibility(
GHOST_TSuccess
GHOST_WindowX11::
setWindowCursorGrab(
- bool grab, bool warp, bool restore
+ GHOST_TGrabCursorMode mode
){
- if(grab) {
- if(warp) {
- m_system->getCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]);
+ if(mode != GHOST_kGrabDisable) {
+ if(mode != GHOST_kGrabNormal) {
+ m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
+ setCursorGrabAccum(0, 0);
+
+ if(mode == GHOST_kGrabHide)
+ setWindowCursorVisibility(false);
- setCursorWarpAccum(0, 0);
- setWindowCursorVisibility(false);
- m_cursorWarp= true;
}
XGrabPointer(m_display, m_window, True, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
}
else {
- if(m_cursorWarp) { /* are we exiting warp */
+ if (m_cursorGrab==GHOST_kGrabHide) {
+ m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
setWindowCursorVisibility(true);
- /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
- if(restore) {
- GHOST_Rect bounds;
- GHOST_TInt32 x_new, y_new, x_rel, y_rel;
-
- getClientBounds(bounds);
-
- x_new= m_cursorWarpInitPos[0]+m_cursorWarpAccumPos[0];
- y_new= m_cursorWarpInitPos[1]+m_cursorWarpAccumPos[1];
-
- screenToClient(x_new, y_new, x_rel, y_rel);
-
- if(x_rel < 0) x_new = (x_new-x_rel) + 2;
- if(y_rel < 0) y_new = (y_new-y_rel) + 2;
- if(x_rel > bounds.getWidth()) x_new -= (x_rel-bounds.getWidth()) + 2;
- if(y_rel > bounds.getHeight()) y_new -= (y_rel-bounds.getHeight()) + 2;
- m_system->setCursorPosition(x_new, y_new);
-
- }
- else {
- m_system->setCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]);
- }
+ }
- setCursorWarpAccum(0, 0);
- m_cursorWarp= false;
+ if(m_cursorGrab != GHOST_kGrabNormal) {
+ /* use to generate a mouse move event, otherwise the last event
+ * blender gets can be outside the screen causing menus not to show
+ * properly unless the user moves the mouse */
+ XWarpPointer(m_display,None,None,0,0,0,0,0,0);
}
+
+ /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
+ setCursorGrabAccum(0, 0);
+ m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1; /* disable */
XUngrabPointer(m_display, CurrentTime);
}
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
index eb0689ab410..0dba1776553 100644
--- a/intern/ghost/intern/GHOST_WindowX11.h
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -256,9 +256,12 @@ protected:
*/
GHOST_TSuccess
setWindowCursorGrab(
- bool grab, bool warp, bool restore
+ GHOST_TGrabCursorMode mode
);
+ GHOST_TGrabCursorMode
+ getWindowCursorGrab() const;
+
/**
* Sets the cursor shape on the window using
* native window system calls.