From f1ff9b69b307fda028fcbcb5749ef9af358d0062 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 15 Jun 2013 15:33:47 +0200 Subject: [PATCH] Mouse grab and relative input need to be disabled when the mouse leaves the window; Disabled resolution switching / window resizing for now due to several glitches --- apps/openmw/mwgui/settingswindow.cpp | 9 ++++- apps/openmw/mwgui/windowmanagerimp.cpp | 10 +++-- apps/openmw/mwinput/inputmanagerimp.cpp | 6 +-- apps/openmw/mwrender/renderingmanager.cpp | 8 ++-- extern/sdl4ogre/sdlinputwrapper.cpp | 46 +++++++++++++++-------- extern/sdl4ogre/sdlinputwrapper.hpp | 4 ++ libs/openengine/ogre/renderer.cpp | 2 +- 7 files changed, 57 insertions(+), 28 deletions(-) diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index edce00d5d5..97bccd01fb 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -269,12 +269,15 @@ namespace MWGui if (index == MyGUI::ITEM_NONE) return; + /* ConfirmationDialog* dialog = MWBase::Environment::get().getWindowManager()->getConfirmationDialog(); dialog->open("#{sNotifyMessage67}"); dialog->eventOkClicked.clear(); dialog->eventOkClicked += MyGUI::newDelegate(this, &SettingsWindow::onResolutionAccept); dialog->eventCancelClicked.clear(); dialog->eventCancelClicked += MyGUI::newDelegate(this, &SettingsWindow::onResolutionCancel); + */ + onResolutionAccept(); } void SettingsWindow::onResolutionAccept() @@ -287,7 +290,9 @@ namespace MWGui Settings::Manager::setInt("resolution y", "Video", resY); apply(); - mResolutionList->setIndexSelected(MyGUI::ITEM_NONE); + + MWBase::Environment::get().getWindowManager()-> + messageBox("New resolution will be applied after a restart", std::vector()); } void SettingsWindow::onResolutionCancel() @@ -356,6 +361,8 @@ namespace MWGui { Settings::Manager::setBool("fullscreen", "Video", newState); apply(); + MWBase::Environment::get().getWindowManager()-> + messageBox("Fullscreen will be applied after a restart", std::vector()); } } else if (_sender == mVSyncButton) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 17c23699fb..eafa9df6e7 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -876,18 +876,18 @@ namespace MWGui setUseHardwareCursors(Settings::Manager::getBool("hardware cursors", "GUI")); - bool changeRes = false; + //bool changeRes = false; bool windowRecreated = false; for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) { - if (it->first == "Video" && ( + /*if (it->first == "Video" && ( it->second == "resolution x" || it->second == "resolution y")) { changeRes = true; - } - else if (it->first == "Video" && it->second == "vsync") + }*/ + if (it->first == "Video" && it->second == "vsync") windowRecreated = true; else if (it->first == "HUD" && it->second == "crosshair") mCrosshairEnabled = Settings::Manager::getBool ("crosshair", "HUD"); @@ -895,6 +895,7 @@ namespace MWGui mSubtitlesEnabled = Settings::Manager::getBool ("subtitles", "GUI"); } + /* if (changeRes) { int x = Settings::Manager::getInt("resolution x", "Video"); @@ -912,6 +913,7 @@ namespace MWGui mDragAndDrop->mDragAndDropWidget->setSize(MyGUI::IntSize(x, y)); mInputBlocker->setSize(MyGUI::IntSize(x,y)); } + */ if (windowRecreated) { mGuiManager->updateWindow (mRendering->getWindow ()); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 7d99f9cc22..1c184883f3 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -220,13 +220,13 @@ namespace MWInput bool was_relative = mInputManager->getMouseRelative(); bool is_relative = !mWindows.isGuiMode(); - //we let the mouse escape in the main menu - mInputManager->setGrabPointer(!main_menu); - // don't keep the pointer away from the window edge in gui mode // stop using raw mouse motions and switch to system cursor movements mInputManager->setMouseRelative(is_relative); + //we let the mouse escape in the main menu + mInputManager->setGrabPointer(!main_menu); + //we switched to non-relative mode, move our cursor to where the in-game //cursor is if( !is_relative && was_relative != is_relative ) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index a60ba30609..22d47cfc03 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -719,7 +719,7 @@ Compositors* RenderingManager::getCompositors() void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings) { - bool changeRes = false; + //bool changeRes = false; bool rebuild = false; // rebuild static geometry (necessary after any material changes) for (Settings::CategorySettingVector::const_iterator it=settings.begin(); it != settings.end(); ++it) @@ -733,11 +733,11 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec if (!MWBase::Environment::get().getWorld()->isCellExterior() && !MWBase::Environment::get().getWorld()->isCellQuasiExterior()) configureFog(*MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()); } - else if (it->first == "Video" && ( + /*else if (it->first == "Video" && ( it->second == "resolution x" || it->second == "resolution y" || it->second == "fullscreen")) - changeRes = true; + changeRes = true;*/ else if (it->second == "field of view" && it->first == "General") mRendering.setFov(Settings::Manager::getFloat("field of view", "General")); else if ((it->second == "texture filtering" && it->first == "General") @@ -791,6 +791,7 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec } } + /* if (changeRes) { unsigned int x = Settings::Manager::getInt("resolution x", "Video"); @@ -807,6 +808,7 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec SDL_SetWindowFullscreen(mRendering.getSDLWindow(), Settings::Manager::getBool("fullscreen", "Video") ? SDL_WINDOW_FULLSCREEN : 0); //mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y); } + */ mWater->processChangedSettings(settings); diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index 7cc7820f90..bd8aa75db7 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -99,9 +99,6 @@ namespace SFO void InputWrapper::capture() { SDL_Event evt; - bool resize=false; - size_t size_x = 0; - size_t size_y = 0; while(SDL_PollEvent(&evt)) { switch(evt.type) @@ -125,25 +122,42 @@ namespace SFO case SDL_MOUSEBUTTONUP: mMouseListener->mouseReleased(evt.button, evt.button.button); break; - case SDL_KEYDOWN: _handleKeyPress(evt.key); break; case SDL_KEYUP: mKeyboardListener->keyReleased(evt.key); break; - case SDL_WINDOWEVENT_RESIZED: - resize = true; - size_x = evt.window.data1; - size_y = evt.window.data2; + case SDL_WINDOWEVENT: + handleWindowEvent(evt); break; case SDL_QUIT: Ogre::Root::getSingleton().queueEndRendering(); break; + default: + std::cerr << "Unhandled SDL event of type " << evt.type << std::endl; + break; } } - if (resize) - mOgreWindow->resize(size_x, size_y); + } + + void InputWrapper::handleWindowEvent(const SDL_Event& evt) + { + switch (evt.window.event) { + case SDL_WINDOWEVENT_ENTER: + mMouseInWindow = true; + break; + case SDL_WINDOWEVENT_LEAVE: + mMouseInWindow = false; + SDL_SetWindowGrab(mSDLWindow, SDL_FALSE); + SDL_SetRelativeMouseMode(SDL_FALSE); + break; + case SDL_WINDOWEVENT_RESIZED: + case SDL_WINDOWEVENT_FOCUS_GAINED: + case SDL_WINDOWEVENT_FOCUS_LOST: + case SDL_WINDOWEVENT_CLOSE: + break; + } } bool InputWrapper::isModifierHeld(int mod) @@ -163,25 +177,25 @@ namespace SFO /// \brief Locks the pointer to the window void InputWrapper::setGrabPointer(bool grab) { - mGrabPointer = grab; - SDL_SetWindowGrab(mSDLWindow, grab ? SDL_TRUE : SDL_FALSE); + mGrabPointer = grab && mMouseInWindow; + SDL_SetWindowGrab(mSDLWindow, grab && mMouseInWindow ? SDL_TRUE : SDL_FALSE); } /// \brief Set the mouse to relative positioning. Doesn't move the cursor /// and disables mouse acceleration. void InputWrapper::setMouseRelative(bool relative) { - if(mMouseRelative == relative) + if(mMouseRelative == relative && mMouseInWindow) return; - mMouseRelative = relative; + mMouseRelative = relative && mMouseInWindow; mWrapPointer = false; //eep, wrap the pointer manually if the input driver doesn't support //relative positioning natively - int success = SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE); - if(relative && success != 0) + int success = SDL_SetRelativeMouseMode(relative && mMouseInWindow ? SDL_TRUE : SDL_FALSE); + if(relative && mMouseInWindow && success != 0) mWrapPointer = true; //now remove all mouse events using the old setting from the queue diff --git a/extern/sdl4ogre/sdlinputwrapper.hpp b/extern/sdl4ogre/sdlinputwrapper.hpp index f84ebcacc1..62141d514d 100644 --- a/extern/sdl4ogre/sdlinputwrapper.hpp +++ b/extern/sdl4ogre/sdlinputwrapper.hpp @@ -38,6 +38,8 @@ namespace SFO private: + void handleWindowEvent(const SDL_Event& evt); + bool _handleWarpMotion(const SDL_MouseMotionEvent& evt); void _wrapMousePointer(const SDL_MouseMotionEvent &evt); MouseMotionEvent _packageMouseMotion(const SDL_Event& evt); @@ -64,6 +66,8 @@ namespace SFO Sint32 mMouseX; Sint32 mMouseY; + bool mMouseInWindow; + SDL_Window* mSDLWindow; Ogre::RenderWindow* mOgreWindow; bool mOwnWindow; diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index e3bba8bfa2..6cf87c4ddb 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -241,7 +241,7 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& SDL_WINDOWPOS_UNDEFINED, // initial y position settings.window_x, // width, in pixels settings.window_y, // height, in pixels - SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE + SDL_WINDOW_SHOWN | (settings.fullscreen ? SDL_WINDOW_FULLSCREEN : 0) );