diff --git a/include/eepp/network/http.hpp b/include/eepp/network/http.hpp index 772276ace..8634592a1 100644 --- a/include/eepp/network/http.hpp +++ b/include/eepp/network/http.hpp @@ -707,6 +707,7 @@ class EE_API Http : NonCopyable { std::list mThreads; Mutex mThreadsMutex; bool mIsSSL; + bool mHostSolved; URI mProxy; void removeOldThreads(); diff --git a/include/eepp/ui/uieventdispatcher.hpp b/include/eepp/ui/uieventdispatcher.hpp index 76ef11192..5e8cabc2f 100644 --- a/include/eepp/ui/uieventdispatcher.hpp +++ b/include/eepp/ui/uieventdispatcher.hpp @@ -13,6 +13,8 @@ class UIEventDispatcher : public EventDispatcher { UIEventDispatcher( SceneNode* sceneNode ); protected: + bool mJustGainedFocus; + void inputCallback( InputEvent* Event ); void checkTabPress( const Uint32& KeyCode ); diff --git a/include/eepp/window/input.hpp b/include/eepp/window/input.hpp index 01a9637eb..9e1c2c17d 100644 --- a/include/eepp/window/input.hpp +++ b/include/eepp/window/input.hpp @@ -33,6 +33,9 @@ class EE_API Input { /** Inject the mouse position given */ virtual void injectMousePos( const Uint16& x, const Uint16& y ) = 0; + /** Gets the current mouse position relative to the focus window */ + virtual Vector2i queryMousePos() = 0; + /** @return If keyboard key was released */ bool isKeyUp( const KeyTable& Key ); diff --git a/include/eepp/window/inputevent.hpp b/include/eepp/window/inputevent.hpp index 0bcaa61be..db629f3c8 100644 --- a/include/eepp/window/inputevent.hpp +++ b/include/eepp/window/inputevent.hpp @@ -1,6 +1,9 @@ #ifndef EE_WINDOWINPUTEVENT_HPP #define EE_WINDOWINPUTEVENT_HPP +#include +#include + namespace EE { namespace Window { #define EE_TEXT_INPUT_SIZE ( 32 ) @@ -10,6 +13,27 @@ namespace EE { namespace Window { class InputEvent { public: + enum WindowEventType { + WindowShown, /**< Window has been shown */ + WindowHidden, /**< Window has been hidden */ + WindowExposed, /**< Window has been exposed and should be redrawn */ + WindowMoved, /**< Window has been moved to data1, data2 */ + WindowResized, /**< Window has been resized to data1xdata2 */ + WindowSizeChanged, /**< The window size has changed, either as a result of an API call or + through the system or user changing the window size. */ + WindowMinimized, /**< Window has been minimized */ + WindowMaximized, /**< Window has been maximized */ + WindowRestored, /**< Window has been restored to normal size and position */ + WindowMouseEnter, /**< Window has gained mouse focus */ + WindowMouseLeave, /**< Window has lost mouse focus */ + WindowKeyboardFocusGain, /**< Window has gained keyboard focus */ + WindowKeyboardFocusLost, /**< Window has lost keyboard focus */ + WindowClose, /**< The window manager requests that the window be closed */ + WindowTakeFocus, /**< Window is being offered a focus (should SetWindowInputFocus() on + itself or a subwindow, or ignore) */ + WindowHitTest /**< Window had a hit test that wasn't SDL_HITTEST_NORMAL. */ + }; + inline InputEvent() : Type( NoEvent ) {} inline InputEvent( Uint32 type ) : Type( type ) {} @@ -21,9 +45,9 @@ class InputEvent { }; /** Application visibility event structure */ - struct ActiveEvent { - Uint8 gain; /** Whether given states were gained or lost (1/0) */ - Uint8 state; /** A mask of the focus states */ + struct WindowEvent { + Uint8 gain; /** Whether given states were gained or lost (1/0) */ + Uint8 type; /** WindowEventType */ }; /** Keyboard event structure */ @@ -138,7 +162,8 @@ class InputEvent { enum EventType { NoEvent = 0, - Active, + EventsSent, + Window, KeyDown, KeyUp, TextInput, @@ -158,7 +183,7 @@ class InputEvent { VideoResize, VideoExpose, EventUser, - EventCount = 32 + EventCount = EventUser - 1 }; /** Event Type */ @@ -166,7 +191,7 @@ class InputEvent { /** General event structure */ union { - ActiveEvent active; + WindowEvent window; KeyboardEvent key; TextInputEvent text; MouseMotionEvent motion; diff --git a/projects/linux/ee.creator.user b/projects/linux/ee.creator.user index 5f2ad28e0..41fdda298 100644 --- a/projects/linux/ee.creator.user +++ b/projects/linux/ee.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/src/eepp/network/http.cpp b/src/eepp/network/http.cpp index c69e00dc8..3dd64757f 100644 --- a/src/eepp/network/http.cpp +++ b/src/eepp/network/http.cpp @@ -558,10 +558,15 @@ void Http::postAsync( const Http::AsyncResponseCallback& cb, const URI& uri, con validateCertificate, proxy ); } -Http::Http() : mConnection( NULL ), mHost(), mPort( 0 ), mIsSSL( false ) {} +Http::Http() : mConnection( NULL ), mHost(), mPort( 0 ), mIsSSL( false ), mHostSolved( false ) {} Http::Http( const std::string& host, unsigned short port, bool useSSL, URI proxy ) : - mConnection( NULL ), mHostName( host ), mPort( port ), mIsSSL( useSSL ), mProxy( proxy ) { + mConnection( NULL ), + mHostName( host ), + mPort( port ), + mIsSSL( useSSL ), + mHostSolved( false ), + mProxy( proxy ) { setHost( host, port, useSSL, proxy ); } @@ -619,10 +624,7 @@ void Http::setHost( const std::string& host, unsigned short port, bool useSSL, U mHostName.erase( mHostName.size() - 1 ); if ( !mProxy.empty() ) { - mHost = IpAddress( mProxy.getHost() ); sameHost = false; - } else { - mHost = IpAddress( mHostName ); } // If the new host is different to the last set host @@ -653,6 +655,16 @@ static bool sendProgress( const Http& http, const Http::Request& request, Http::Response Http::downloadRequest( const Http::Request& request, IOStream& writeTo, Time timeout ) { + // Solve the host IP only when the request starts. + if ( !mHostSolved ) { + if ( !mProxy.empty() ) { + mHost = IpAddress( mProxy.getHost() ); + } else { + mHost = IpAddress( mHostName ); + } + mHostSolved = true; + } + if ( 0 == mHost.toInteger() ) { return Response(); } diff --git a/src/eepp/scene/eventdispatcher.cpp b/src/eepp/scene/eventdispatcher.cpp index 9dbc78712..e0bc84f74 100644 --- a/src/eepp/scene/eventdispatcher.cpp +++ b/src/eepp/scene/eventdispatcher.cpp @@ -35,6 +35,13 @@ EventDispatcher::~EventDispatcher() { void EventDispatcher::inputCallback( InputEvent* Event ) { switch ( Event->Type ) { + case InputEvent::Window: { + if ( Event->window.type == InputEvent::WindowKeyboardFocusGain ) { + mMousePosi = mInput->queryMousePos(); + mMousePos = mMousePosi.asFloat(); + } + break; + } case InputEvent::KeyUp: sendKeyUp( Event->key.keysym.sym, Event->key.keysym.unicode, Event->key.keysym.mod ); break; diff --git a/src/eepp/ui/uieventdispatcher.cpp b/src/eepp/ui/uieventdispatcher.cpp index e5c33aff3..3500056e6 100644 --- a/src/eepp/ui/uieventdispatcher.cpp +++ b/src/eepp/ui/uieventdispatcher.cpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace EE { namespace UI { @@ -9,22 +10,33 @@ UIEventDispatcher* UIEventDispatcher::New( SceneNode* sceneNode ) { return eeNew( UIEventDispatcher, ( sceneNode ) ); } -UIEventDispatcher::UIEventDispatcher( SceneNode* sceneNode ) : EventDispatcher( sceneNode ) {} +UIEventDispatcher::UIEventDispatcher( SceneNode* sceneNode ) : + EventDispatcher( sceneNode ), mJustGainedFocus( false ) {} void UIEventDispatcher::inputCallback( InputEvent* Event ) { EventDispatcher::inputCallback( Event ); switch ( Event->Type ) { + case InputEvent::Window: + if ( Event->window.type == InputEvent::WindowKeyboardFocusGain ) { + mJustGainedFocus = true; + } + break; case InputEvent::KeyDown: checkTabPress( Event->key.keysym.sym ); break; + case InputEvent::EventsSent: + mJustGainedFocus = false; + break; } } void UIEventDispatcher::checkTabPress( const Uint32& KeyCode ) { eeASSERT( NULL != mFocusControl ); - if ( KeyCode == KEY_TAB && mFocusControl->isUINode() ) { + Window::Window* win = mFocusControl->getSceneNode()->getWindow(); + if ( KeyCode == KEY_TAB && mFocusControl->isUINode() && NULL != win && win->isActive() && + !mJustGainedFocus ) { Node* Ctrl = static_cast( mFocusControl )->getNextWidget(); if ( NULL != Ctrl ) diff --git a/src/eepp/window/backend/SDL2/inputsdl2.cpp b/src/eepp/window/backend/SDL2/inputsdl2.cpp index d3e792723..b5c48ae29 100644 --- a/src/eepp/window/backend/SDL2/inputsdl2.cpp +++ b/src/eepp/window/backend/SDL2/inputsdl2.cpp @@ -35,47 +35,97 @@ void InputSDL::update() { EEEvent.Type = InputEvent::VideoResize; EEEvent.resize.w = SDLEvent.window.data1 * mDPIScale; EEEvent.resize.h = SDLEvent.window.data2 * mDPIScale; + EEEvent.window.type = InputEvent::WindowResized; + break; + } + case SDL_WINDOWEVENT_HIT_TEST: { + EEEvent.Type = InputEvent::Window; + EEEvent.window.gain = 1; + EEEvent.window.type = InputEvent::WindowHitTest; + break; + } + case SDL_WINDOWEVENT_TAKE_FOCUS: { + EEEvent.Type = InputEvent::VideoExpose; + EEEvent.expose.type = EEEvent.Type; + EEEvent.window.type = InputEvent::WindowTakeFocus; + break; + } + case SDL_WINDOWEVENT_CLOSE: { + EEEvent.Type = InputEvent::Window; + EEEvent.window.gain = 0; + EEEvent.window.type = InputEvent::WindowClose; + break; + } + case SDL_WINDOWEVENT_SIZE_CHANGED: { + EEEvent.Type = InputEvent::Window; + EEEvent.window.gain = 1; + EEEvent.window.type = InputEvent::WindowSizeChanged; + break; + } + case SDL_WINDOWEVENT_MAXIMIZED: { + EEEvent.Type = InputEvent::Window; + EEEvent.window.gain = 1; + EEEvent.window.type = InputEvent::WindowMaximized; break; } case SDL_WINDOWEVENT_EXPOSED: { EEEvent.Type = InputEvent::VideoExpose; EEEvent.expose.type = EEEvent.Type; + EEEvent.window.type = InputEvent::WindowExposed; + break; + } + case SDL_WINDOWEVENT_MOVED: { + EEEvent.Type = InputEvent::Window; + EEEvent.window.gain = 1; + EEEvent.window.type = InputEvent::WindowMoved; + break; + } + case SDL_WINDOWEVENT_SHOWN: { + EEEvent.Type = InputEvent::Window; + EEEvent.window.gain = 1; + EEEvent.window.type = InputEvent::WindowShown; + break; + } + case SDL_WINDOWEVENT_HIDDEN: { + EEEvent.Type = InputEvent::Window; + EEEvent.window.gain = 0; + EEEvent.window.type = InputEvent::WindowHidden; break; } case SDL_WINDOWEVENT_MINIMIZED: { - EEEvent.Type = InputEvent::Active; - EEEvent.active.gain = 0; - EEEvent.active.state = EE_APPACTIVE; + EEEvent.Type = InputEvent::Window; + EEEvent.window.gain = 0; + EEEvent.window.type = InputEvent::WindowMinimized; break; } case SDL_WINDOWEVENT_RESTORED: { - EEEvent.Type = InputEvent::Active; - EEEvent.active.gain = 1; - EEEvent.active.state = EE_APPACTIVE; + EEEvent.Type = InputEvent::Window; + EEEvent.window.gain = 1; + EEEvent.window.type = InputEvent::WindowRestored; break; } case SDL_WINDOWEVENT_ENTER: { - EEEvent.Type = InputEvent::Active; - EEEvent.active.gain = 1; - EEEvent.active.state = EE_APPMOUSEFOCUS; + EEEvent.Type = InputEvent::Window; + EEEvent.window.gain = 1; + EEEvent.window.type = InputEvent::WindowMouseEnter; break; } case SDL_WINDOWEVENT_LEAVE: { - EEEvent.Type = InputEvent::Active; - EEEvent.active.gain = 0; - EEEvent.active.state = EE_APPMOUSEFOCUS; + EEEvent.Type = InputEvent::Window; + EEEvent.window.gain = 0; + EEEvent.window.type = InputEvent::WindowMouseLeave; break; } case SDL_WINDOWEVENT_FOCUS_GAINED: { - EEEvent.Type = InputEvent::Active; - EEEvent.active.gain = 1; - EEEvent.active.state = EE_APPINPUTFOCUS; + EEEvent.Type = InputEvent::Window; + EEEvent.window.gain = 1; + EEEvent.window.type = InputEvent::WindowKeyboardFocusGain; break; } case SDL_WINDOWEVENT_FOCUS_LOST: { - EEEvent.Type = InputEvent::Active; - EEEvent.active.gain = 0; - EEEvent.active.state = EE_APPINPUTFOCUS; + EEEvent.Type = InputEvent::Window; + EEEvent.window.gain = 0; + EEEvent.window.type = InputEvent::WindowKeyboardFocusLost; break; } } @@ -278,6 +328,10 @@ void InputSDL::update() { processEvent( &EEEvent ); } } + + InputEvent endProcessingEvent; + endProcessingEvent.Type = InputEvent::EventsSent; + processEvent( &endProcessingEvent ); } bool InputSDL::grabInput() { @@ -296,23 +350,30 @@ void InputSDL::injectMousePos( const Uint16& x, const Uint16& y ) { SDL_WarpMouseInWindow( reinterpret_cast( mWindow )->GetSDLWindow(), x, y ); } +Vector2i InputSDL::queryMousePos() { +#if SDL_VERSION_ATLEAST( 2, 0, 5 ) + Vector2i mousePos; + Vector2i tempMouse; + Vector2i tempWinPos; + Rect bordersSize; + SDL_Window* sdlw = reinterpret_cast( mWindow )->GetSDLWindow(); + SDL_GetGlobalMouseState( &tempMouse.x, &tempMouse.y ); + SDL_GetWindowPosition( sdlw, &tempWinPos.x, &tempWinPos.y ); + SDL_GetWindowBordersSize( sdlw, &bordersSize.Top, &bordersSize.Left, &bordersSize.Bottom, + &bordersSize.Right ); + mousePos.x = (int)tempMouse.x - tempWinPos.x - bordersSize.Left; + mousePos.y = (int)tempMouse.y - tempWinPos.y - bordersSize.Top; + return mousePos; +#else + int x, y; + SDL_GetMouseState( &x, &y ); + return Vector2i( x, y ); +#endif +} + void InputSDL::init() { mDPIScale = mWindow->getScale(); - -#if SDL_VERSION_ATLEAST( 2, 0, 5 ) - Vector2i mTempMouse; - Vector2i mTempWinPos; - Rect mBordersSize; - - SDL_Window* sdlw = reinterpret_cast( mWindow )->GetSDLWindow(); - SDL_GetGlobalMouseState( &mTempMouse.x, &mTempMouse.y ); - SDL_GetWindowPosition( sdlw, &mTempWinPos.x, &mTempWinPos.y ); - SDL_GetWindowBordersSize( sdlw, &mBordersSize.Top, &mBordersSize.Left, &mBordersSize.Bottom, - &mBordersSize.Right ); - - mMousePos.x = (int)mTempMouse.x - mTempWinPos.x - mBordersSize.Left; - mMousePos.y = (int)mTempMouse.y - mTempWinPos.y - mBordersSize.Top; -#endif + mMousePos = queryMousePos(); initializeTables(); diff --git a/src/eepp/window/backend/SDL2/inputsdl2.hpp b/src/eepp/window/backend/SDL2/inputsdl2.hpp index 3cb8b43db..798b361b1 100644 --- a/src/eepp/window/backend/SDL2/inputsdl2.hpp +++ b/src/eepp/window/backend/SDL2/inputsdl2.hpp @@ -22,6 +22,8 @@ class EE_API InputSDL : public Input { void injectMousePos( const Uint16& x, const Uint16& y ); + Vector2i queryMousePos(); + protected: friend class WindowSDL; Float mDPIScale; diff --git a/src/eepp/window/input.cpp b/src/eepp/window/input.cpp index c42561f60..6e816cfd7 100644 --- a/src/eepp/window/input.cpp +++ b/src/eepp/window/input.cpp @@ -50,6 +50,12 @@ void Input::sendEvent( InputEvent* Event ) { void Input::processEvent( InputEvent* Event ) { switch ( Event->Type ) { + case InputEvent::Window: { + if ( Event->window.type == InputEvent::WindowKeyboardFocusGain ) { + mMousePos = queryMousePos(); + } + break; + } case InputEvent::KeyDown: { if ( Event->key.keysym.sym > EE_KEYS_NUM ) break; diff --git a/src/examples/http_request/http_request.cpp b/src/examples/http_request/http_request.cpp index 6c24504c7..4bd319716 100644 --- a/src/examples/http_request/http_request.cpp +++ b/src/examples/http_request/http_request.cpp @@ -187,12 +187,19 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) { // Set the proxy for the request char* http_proxy = getenv( "http_proxy" ); + std::string httpProxy; if ( !proxy && NULL != http_proxy ) { - http.setProxy( URI( http_proxy ) ); + httpProxy = std::string( http_proxy ); } else if ( proxy ) { - http.setProxy( URI( proxy.Get() ) ); + httpProxy = proxy.Get(); } + if ( httpProxy.find( "://" ) == std::string::npos ) { + httpProxy = "http://" + httpProxy; + } + + http.setProxy( URI( httpProxy ) ); + // Request a compressed response if ( compressed ) { request.setCompressedResponse( true );