1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-28 08:37:12 +00:00

Release and show the cursor when focus lost

This commit is contained in:
scrawl 2013-11-20 16:05:24 +01:00
parent 5a4bd9b202
commit 7f735c2c4c
9 changed files with 66 additions and 47 deletions

View File

@ -284,6 +284,9 @@ namespace MWBase
virtual void setKeyFocusWidget (MyGUI::Widget* widget) = 0; virtual void setKeyFocusWidget (MyGUI::Widget* widget) = 0;
virtual Loading::Listener* getLoadingScreen() = 0; virtual Loading::Listener* getLoadingScreen() = 0;
/// Should the cursor be visible?
virtual bool getCursorVisible() = 0;
}; };
} }

View File

@ -180,7 +180,7 @@ namespace MWGui
mCursorManager->setEnabled(true); mCursorManager->setEnabled(true);
onCursorChange(MyGUI::PointerManager::getInstance().getDefaultPointer()); onCursorChange(MyGUI::PointerManager::getInstance().getDefaultPointer());
mCursorManager->cursorVisibilityChange(false); SDL_ShowCursor(false);
// hide mygui's pointer // hide mygui's pointer
MyGUI::PointerManager::getInstance().setVisible(false); MyGUI::PointerManager::getInstance().setVisible(false);
@ -879,11 +879,7 @@ namespace MWGui
void WindowManager::setCursorVisible(bool visible) void WindowManager::setCursorVisible(bool visible)
{ {
if(mCursorVisible == visible)
return;
mCursorVisible = visible; mCursorVisible = visible;
mCursorManager->cursorVisibilityChange(visible);
} }
void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result) void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result)
@ -1362,4 +1358,9 @@ namespace MWGui
mRecharge->start(soulgem); mRecharge->start(soulgem);
} }
bool WindowManager::getCursorVisible()
{
return mCursorVisible;
}
} }

View File

@ -278,6 +278,8 @@ namespace MWGui
void onSoulgemDialogButtonPressed (int button); void onSoulgemDialogButtonPressed (int button);
virtual bool getCursorVisible();
private: private:
bool mConsoleOnlyScripts; bool mConsoleOnlyScripts;

View File

@ -264,6 +264,8 @@ namespace MWInput
void InputManager::update(float dt, bool loading) void InputManager::update(float dt, bool loading)
{ {
mInputManager->setMouseVisible(MWBase::Environment::get().getWindowManager()->getCursorVisible());
mInputManager->capture(loading); mInputManager->capture(loading);
// inject some fake mouse movement to force updating MyGUI's widget states // inject some fake mouse movement to force updating MyGUI's widget states
// this shouldn't do any harm since we're moving back to the original position afterwards // this shouldn't do any harm since we're moving back to the original position afterwards

View File

@ -22,9 +22,6 @@ public:
/// \brief Follow up a cursorChanged() call with enough info to create an cursor. /// \brief Follow up a cursorChanged() call with enough info to create an cursor.
virtual void receiveCursorInfo(const std::string &name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) = 0; virtual void receiveCursorInfo(const std::string &name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) = 0;
/// \brief Tell the manager when the cursor visibility changed
virtual void cursorVisibilityChange(bool visible) = 0;
/// \brief sets whether to actively manage cursors or not /// \brief sets whether to actively manage cursors or not
virtual void setEnabled(bool enabled) = 0; virtual void setEnabled(bool enabled) = 0;
}; };

View File

@ -10,7 +10,6 @@ namespace SFO
SDLCursorManager::SDLCursorManager() : SDLCursorManager::SDLCursorManager() :
mEnabled(false), mEnabled(false),
mCursorVisible(false),
mInitialized(false) mInitialized(false)
{ {
} }
@ -70,27 +69,7 @@ namespace SFO
void SDLCursorManager::_setGUICursor(const std::string &name) void SDLCursorManager::_setGUICursor(const std::string &name)
{ {
if(mEnabled && mCursorVisible) SDL_SetCursor(mCursorMap.find(name)->second);
{
SDL_SetCursor(mCursorMap.find(name)->second);
_setCursorVisible(mCursorVisible);
}
}
void SDLCursorManager::_setCursorVisible(bool visible)
{
if(!mEnabled)
return;
SDL_ShowCursor(visible ? SDL_TRUE : SDL_FALSE);
}
void SDLCursorManager::cursorVisibilityChange(bool visible)
{
mCursorVisible = visible;
_setGUICursor(mCurrentCursor);
_setCursorVisible(visible);
} }
void SDLCursorManager::receiveCursorInfo(const std::string& name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) void SDLCursorManager::receiveCursorInfo(const std::string& name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y)

View File

@ -19,14 +19,12 @@ namespace SFO
virtual bool cursorChanged(const std::string &name); virtual bool cursorChanged(const std::string &name);
virtual void receiveCursorInfo(const std::string &name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y); virtual void receiveCursorInfo(const std::string &name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y);
virtual void cursorVisibilityChange(bool visible);
private: private:
void _createCursorFromResource(const std::string &name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y); void _createCursorFromResource(const std::string &name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y);
void _putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel); void _putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
void _setGUICursor(const std::string& name); void _setGUICursor(const std::string& name);
void _setCursorVisible(bool visible);
typedef std::map<std::string, SDL_Cursor*> CursorMap; typedef std::map<std::string, SDL_Cursor*> CursorMap;
CursorMap mCursorMap; CursorMap mCursorMap;
@ -34,7 +32,6 @@ namespace SFO
std::string mCurrentCursor; std::string mCurrentCursor;
bool mEnabled; bool mEnabled;
bool mInitialized; bool mInitialized;
bool mCursorVisible;
}; };
} }

View File

@ -23,7 +23,11 @@ namespace SFO
mJoyListener(NULL), mJoyListener(NULL),
mKeyboardListener(NULL), mKeyboardListener(NULL),
mMouseListener(NULL), mMouseListener(NULL),
mWindowListener(NULL) mWindowListener(NULL),
mWindowHasFocus(true),
mWantGrab(false),
mWantRelative(false),
mWantMouseVisible(false)
{ {
_setupOISKeys(); _setupOISKeys();
} }
@ -51,13 +55,16 @@ namespace SFO
switch(evt.type) switch(evt.type)
{ {
case SDL_MOUSEMOTION: case SDL_MOUSEMOTION:
//ignore this if it happened due to a warp // Ignore this if it happened due to a warp
if(!_handleWarpMotion(evt.motion)) if(!_handleWarpMotion(evt.motion))
{ {
mMouseListener->mouseMoved(_packageMouseMotion(evt)); // If in relative mode, don't trigger events unless window has focus
if (!mWantRelative || mWindowHasFocus)
mMouseListener->mouseMoved(_packageMouseMotion(evt));
//try to keep the mouse inside the window // Try to keep the mouse inside the window
_wrapMousePointer(evt.motion); if (mWindowHasFocus)
_wrapMousePointer(evt.motion);
} }
break; break;
case SDL_MOUSEWHEEL: case SDL_MOUSEWHEEL:
@ -118,11 +125,11 @@ namespace SFO
switch (evt.window.event) { switch (evt.window.event) {
case SDL_WINDOWEVENT_ENTER: case SDL_WINDOWEVENT_ENTER:
mMouseInWindow = true; mMouseInWindow = true;
updateMouseSettings();
break; break;
case SDL_WINDOWEVENT_LEAVE: case SDL_WINDOWEVENT_LEAVE:
mMouseInWindow = false; mMouseInWindow = false;
SDL_SetWindowGrab(mSDLWindow, SDL_FALSE); updateMouseSettings();
SDL_SetRelativeMouseMode(SDL_FALSE);
break; break;
case SDL_WINDOWEVENT_SIZE_CHANGED: case SDL_WINDOWEVENT_SIZE_CHANGED:
int w,h; int w,h;
@ -149,10 +156,15 @@ namespace SFO
break; break;
case SDL_WINDOWEVENT_FOCUS_GAINED: case SDL_WINDOWEVENT_FOCUS_GAINED:
mWindowHasFocus = true;
updateMouseSettings();
if (mWindowListener) if (mWindowListener)
mWindowListener->windowFocusChange(true); mWindowListener->windowFocusChange(true);
break; break;
case SDL_WINDOWEVENT_FOCUS_LOST: case SDL_WINDOWEVENT_FOCUS_LOST:
mWindowHasFocus = false;
updateMouseSettings();
if (mWindowListener) if (mWindowListener)
mWindowListener->windowFocusChange(false); mWindowListener->windowFocusChange(false);
break; break;
@ -193,25 +205,43 @@ namespace SFO
/// \brief Locks the pointer to the window /// \brief Locks the pointer to the window
void InputWrapper::setGrabPointer(bool grab) void InputWrapper::setGrabPointer(bool grab)
{ {
mGrabPointer = grab && mMouseInWindow; mWantGrab = grab;
SDL_SetWindowGrab(mSDLWindow, grab && mMouseInWindow ? SDL_TRUE : SDL_FALSE); updateMouseSettings();
} }
/// \brief Set the mouse to relative positioning. Doesn't move the cursor /// \brief Set the mouse to relative positioning. Doesn't move the cursor
/// and disables mouse acceleration. /// and disables mouse acceleration.
void InputWrapper::setMouseRelative(bool relative) void InputWrapper::setMouseRelative(bool relative)
{ {
if(mMouseRelative == relative && mMouseInWindow) mWantRelative = relative;
updateMouseSettings();
}
void InputWrapper::setMouseVisible(bool visible)
{
mWantMouseVisible = visible;
updateMouseSettings();
}
void InputWrapper::updateMouseSettings()
{
mGrabPointer = mWantGrab && mMouseInWindow && mWindowHasFocus;
SDL_SetWindowGrab(mSDLWindow, mGrabPointer ? SDL_TRUE : SDL_FALSE);
SDL_ShowCursor(mWantMouseVisible || !mWindowHasFocus);
bool relative = mWantRelative && mMouseInWindow && mWindowHasFocus;
if(mMouseRelative == relative)
return; return;
mMouseRelative = relative && mMouseInWindow; mMouseRelative = relative;
mWrapPointer = false; mWrapPointer = false;
//eep, wrap the pointer manually if the input driver doesn't support //eep, wrap the pointer manually if the input driver doesn't support
//relative positioning natively //relative positioning natively
int success = SDL_SetRelativeMouseMode(relative && mMouseInWindow ? SDL_TRUE : SDL_FALSE); int success = SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE);
if(relative && mMouseInWindow && success != 0) if(relative && success != 0)
mWrapPointer = true; mWrapPointer = true;
//now remove all mouse events using the old setting from the queue //now remove all mouse events using the old setting from the queue

View File

@ -28,6 +28,7 @@ namespace SFO
bool isModifierHeld(SDL_Keymod mod); bool isModifierHeld(SDL_Keymod mod);
bool isKeyDown(SDL_Scancode key); bool isKeyDown(SDL_Scancode key);
void setMouseVisible (bool visible);
void setMouseRelative(bool relative); void setMouseRelative(bool relative);
bool getMouseRelative() { return mMouseRelative; } bool getMouseRelative() { return mMouseRelative; }
void setGrabPointer(bool grab); void setGrabPointer(bool grab);
@ -36,6 +37,8 @@ namespace SFO
void warpMouse(int x, int y); void warpMouse(int x, int y);
void updateMouseSettings();
private: private:
void handleWindowEvent(const SDL_Event& evt); void handleWindowEvent(const SDL_Event& evt);
@ -57,14 +60,19 @@ namespace SFO
Uint16 mWarpX; Uint16 mWarpX;
Uint16 mWarpY; Uint16 mWarpY;
bool mWarpCompensate; bool mWarpCompensate;
bool mMouseRelative;
bool mWrapPointer; bool mWrapPointer;
bool mWantMouseVisible;
bool mWantGrab;
bool mWantRelative;
bool mGrabPointer; bool mGrabPointer;
bool mMouseRelative;
Sint32 mMouseZ; Sint32 mMouseZ;
Sint32 mMouseX; Sint32 mMouseX;
Sint32 mMouseY; Sint32 mMouseY;
bool mWindowHasFocus;
bool mMouseInWindow; bool mMouseInWindow;
SDL_Window* mSDLWindow; SDL_Window* mSDLWindow;