mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 00:26:39 +00:00 
			
		
		
		
	Release and show the cursor when focus lost
This commit is contained in:
		
							parent
							
								
									5a4bd9b202
								
							
						
					
					
						commit
						7f735c2c4c
					
				
					 9 changed files with 66 additions and 47 deletions
				
			
		| 
						 | 
				
			
			@ -284,6 +284,9 @@ namespace MWBase
 | 
			
		|||
            virtual void setKeyFocusWidget (MyGUI::Widget* widget) = 0;
 | 
			
		||||
 | 
			
		||||
            virtual Loading::Listener* getLoadingScreen() = 0;
 | 
			
		||||
 | 
			
		||||
            /// Should the cursor be visible?
 | 
			
		||||
            virtual bool getCursorVisible() = 0;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -180,7 +180,7 @@ namespace MWGui
 | 
			
		|||
        mCursorManager->setEnabled(true);
 | 
			
		||||
 | 
			
		||||
        onCursorChange(MyGUI::PointerManager::getInstance().getDefaultPointer());
 | 
			
		||||
        mCursorManager->cursorVisibilityChange(false);
 | 
			
		||||
        SDL_ShowCursor(false);
 | 
			
		||||
 | 
			
		||||
        // hide mygui's pointer
 | 
			
		||||
        MyGUI::PointerManager::getInstance().setVisible(false);
 | 
			
		||||
| 
						 | 
				
			
			@ -879,11 +879,7 @@ namespace MWGui
 | 
			
		|||
 | 
			
		||||
    void WindowManager::setCursorVisible(bool visible)
 | 
			
		||||
    {
 | 
			
		||||
        if(mCursorVisible == visible)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        mCursorVisible = visible;
 | 
			
		||||
        mCursorManager->cursorVisibilityChange(visible);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result)
 | 
			
		||||
| 
						 | 
				
			
			@ -1362,4 +1358,9 @@ namespace MWGui
 | 
			
		|||
        mRecharge->start(soulgem);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool WindowManager::getCursorVisible()
 | 
			
		||||
    {
 | 
			
		||||
        return mCursorVisible;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -278,6 +278,8 @@ namespace MWGui
 | 
			
		|||
 | 
			
		||||
    void onSoulgemDialogButtonPressed (int button);
 | 
			
		||||
 | 
			
		||||
    virtual bool getCursorVisible();
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    bool mConsoleOnlyScripts;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -264,6 +264,8 @@ namespace MWInput
 | 
			
		|||
 | 
			
		||||
    void InputManager::update(float dt, bool loading)
 | 
			
		||||
    {
 | 
			
		||||
        mInputManager->setMouseVisible(MWBase::Environment::get().getWindowManager()->getCursorVisible());
 | 
			
		||||
 | 
			
		||||
        mInputManager->capture(loading);
 | 
			
		||||
        // 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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								extern/sdl4ogre/cursormanager.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								extern/sdl4ogre/cursormanager.hpp
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -22,9 +22,6 @@ public:
 | 
			
		|||
    /// \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;
 | 
			
		||||
 | 
			
		||||
    /// \brief Tell the manager when the cursor visibility changed
 | 
			
		||||
    virtual void cursorVisibilityChange(bool visible) = 0;
 | 
			
		||||
 | 
			
		||||
    /// \brief sets whether to actively manage cursors or not
 | 
			
		||||
    virtual void setEnabled(bool enabled) = 0;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										23
									
								
								extern/sdl4ogre/sdlcursormanager.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								extern/sdl4ogre/sdlcursormanager.cpp
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -10,7 +10,6 @@ namespace SFO
 | 
			
		|||
 | 
			
		||||
    SDLCursorManager::SDLCursorManager() :
 | 
			
		||||
        mEnabled(false),
 | 
			
		||||
        mCursorVisible(false),
 | 
			
		||||
        mInitialized(false)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -70,27 +69,7 @@ namespace SFO
 | 
			
		|||
 | 
			
		||||
    void SDLCursorManager::_setGUICursor(const std::string &name)
 | 
			
		||||
    {
 | 
			
		||||
        if(mEnabled && mCursorVisible)
 | 
			
		||||
        {
 | 
			
		||||
            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);
 | 
			
		||||
        SDL_SetCursor(mCursorMap.find(name)->second);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void SDLCursorManager::receiveCursorInfo(const std::string& name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								extern/sdl4ogre/sdlcursormanager.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								extern/sdl4ogre/sdlcursormanager.hpp
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -19,14 +19,12 @@ namespace SFO
 | 
			
		|||
 | 
			
		||||
        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 cursorVisibilityChange(bool visible);
 | 
			
		||||
 | 
			
		||||
    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 _putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
 | 
			
		||||
 | 
			
		||||
        void _setGUICursor(const std::string& name);
 | 
			
		||||
        void _setCursorVisible(bool visible);
 | 
			
		||||
 | 
			
		||||
        typedef std::map<std::string, SDL_Cursor*> CursorMap;
 | 
			
		||||
        CursorMap mCursorMap;
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +32,6 @@ namespace SFO
 | 
			
		|||
        std::string mCurrentCursor;
 | 
			
		||||
        bool mEnabled;
 | 
			
		||||
        bool mInitialized;
 | 
			
		||||
        bool mCursorVisible;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										56
									
								
								extern/sdl4ogre/sdlinputwrapper.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										56
									
								
								extern/sdl4ogre/sdlinputwrapper.cpp
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -23,7 +23,11 @@ namespace SFO
 | 
			
		|||
        mJoyListener(NULL),
 | 
			
		||||
        mKeyboardListener(NULL),
 | 
			
		||||
        mMouseListener(NULL),
 | 
			
		||||
        mWindowListener(NULL)
 | 
			
		||||
        mWindowListener(NULL),
 | 
			
		||||
        mWindowHasFocus(true),
 | 
			
		||||
        mWantGrab(false),
 | 
			
		||||
        mWantRelative(false),
 | 
			
		||||
        mWantMouseVisible(false)
 | 
			
		||||
    {
 | 
			
		||||
        _setupOISKeys();
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -51,13 +55,16 @@ namespace SFO
 | 
			
		|||
            switch(evt.type)
 | 
			
		||||
            {
 | 
			
		||||
                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))
 | 
			
		||||
                    {
 | 
			
		||||
                        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
 | 
			
		||||
                        _wrapMousePointer(evt.motion);
 | 
			
		||||
                        // Try to keep the mouse inside the window
 | 
			
		||||
                        if (mWindowHasFocus)
 | 
			
		||||
                            _wrapMousePointer(evt.motion);
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                case SDL_MOUSEWHEEL:
 | 
			
		||||
| 
						 | 
				
			
			@ -118,11 +125,11 @@ namespace SFO
 | 
			
		|||
        switch (evt.window.event) {
 | 
			
		||||
            case SDL_WINDOWEVENT_ENTER:
 | 
			
		||||
                mMouseInWindow = true;
 | 
			
		||||
                updateMouseSettings();
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_WINDOWEVENT_LEAVE:
 | 
			
		||||
                mMouseInWindow = false;
 | 
			
		||||
                SDL_SetWindowGrab(mSDLWindow, SDL_FALSE);
 | 
			
		||||
                SDL_SetRelativeMouseMode(SDL_FALSE);
 | 
			
		||||
                updateMouseSettings();
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_WINDOWEVENT_SIZE_CHANGED:
 | 
			
		||||
                int w,h;
 | 
			
		||||
| 
						 | 
				
			
			@ -149,10 +156,15 @@ namespace SFO
 | 
			
		|||
                break;
 | 
			
		||||
 | 
			
		||||
            case SDL_WINDOWEVENT_FOCUS_GAINED:
 | 
			
		||||
                mWindowHasFocus = true;
 | 
			
		||||
                updateMouseSettings();
 | 
			
		||||
                if (mWindowListener)
 | 
			
		||||
                    mWindowListener->windowFocusChange(true);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_WINDOWEVENT_FOCUS_LOST:
 | 
			
		||||
                mWindowHasFocus = false;
 | 
			
		||||
                updateMouseSettings();
 | 
			
		||||
                if (mWindowListener)
 | 
			
		||||
                    mWindowListener->windowFocusChange(false);
 | 
			
		||||
                break;
 | 
			
		||||
| 
						 | 
				
			
			@ -193,25 +205,43 @@ namespace SFO
 | 
			
		|||
    /// \brief Locks the pointer to the window
 | 
			
		||||
    void InputWrapper::setGrabPointer(bool grab)
 | 
			
		||||
    {
 | 
			
		||||
        mGrabPointer = grab && mMouseInWindow;
 | 
			
		||||
        SDL_SetWindowGrab(mSDLWindow, grab && mMouseInWindow ? SDL_TRUE : SDL_FALSE);
 | 
			
		||||
        mWantGrab = grab;
 | 
			
		||||
        updateMouseSettings();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// \brief Set the mouse to relative positioning. Doesn't move the cursor
 | 
			
		||||
    ///        and disables mouse acceleration.
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
        mMouseRelative = relative && mMouseInWindow;
 | 
			
		||||
        mMouseRelative = relative;
 | 
			
		||||
 | 
			
		||||
        mWrapPointer = false;
 | 
			
		||||
 | 
			
		||||
        //eep, wrap the pointer manually if the input driver doesn't support
 | 
			
		||||
        //relative positioning natively
 | 
			
		||||
        int success = SDL_SetRelativeMouseMode(relative && mMouseInWindow ? SDL_TRUE : SDL_FALSE);
 | 
			
		||||
        if(relative && mMouseInWindow && success != 0)
 | 
			
		||||
        int success = SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE);
 | 
			
		||||
        if(relative && success != 0)
 | 
			
		||||
            mWrapPointer = true;
 | 
			
		||||
 | 
			
		||||
        //now remove all mouse events using the old setting from the queue
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								extern/sdl4ogre/sdlinputwrapper.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								extern/sdl4ogre/sdlinputwrapper.hpp
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -28,6 +28,7 @@ namespace SFO
 | 
			
		|||
		bool isModifierHeld(SDL_Keymod mod);
 | 
			
		||||
		bool isKeyDown(SDL_Scancode key);
 | 
			
		||||
 | 
			
		||||
        void setMouseVisible (bool visible);
 | 
			
		||||
        void setMouseRelative(bool relative);
 | 
			
		||||
        bool getMouseRelative() { return mMouseRelative; }
 | 
			
		||||
        void setGrabPointer(bool grab);
 | 
			
		||||
| 
						 | 
				
			
			@ -36,6 +37,8 @@ namespace SFO
 | 
			
		|||
 | 
			
		||||
        void warpMouse(int x, int y);
 | 
			
		||||
 | 
			
		||||
        void updateMouseSettings();
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        void handleWindowEvent(const SDL_Event& evt);
 | 
			
		||||
| 
						 | 
				
			
			@ -57,14 +60,19 @@ namespace SFO
 | 
			
		|||
        Uint16 mWarpX;
 | 
			
		||||
        Uint16 mWarpY;
 | 
			
		||||
        bool mWarpCompensate;
 | 
			
		||||
        bool mMouseRelative;
 | 
			
		||||
        bool mWrapPointer;
 | 
			
		||||
 | 
			
		||||
        bool mWantMouseVisible;
 | 
			
		||||
        bool mWantGrab;
 | 
			
		||||
        bool mWantRelative;
 | 
			
		||||
        bool mGrabPointer;
 | 
			
		||||
        bool mMouseRelative;
 | 
			
		||||
 | 
			
		||||
        Sint32 mMouseZ;
 | 
			
		||||
        Sint32 mMouseX;
 | 
			
		||||
        Sint32 mMouseY;
 | 
			
		||||
 | 
			
		||||
        bool mWindowHasFocus;
 | 
			
		||||
        bool mMouseInWindow;
 | 
			
		||||
 | 
			
		||||
        SDL_Window* mSDLWindow;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue