void Widget::SetAllocation( const sf::FloatRect& rect ) { sf::FloatRect oldallocation( m_allocation ); // Make sure allocation is pixel-aligned. m_allocation.left = std::floor( rect.left + .5f ); m_allocation.top = std::floor( rect.top + .5f ); m_allocation.width = std::floor( rect.width + .5f ); m_allocation.height = std::floor( rect.height + .5f ); if( oldallocation.top == m_allocation.top && oldallocation.left == m_allocation.left && oldallocation.width == m_allocation.width && oldallocation.height == m_allocation.height ) { // Nothing even changed. Save the hierarchy the trouble. return; } if( ( oldallocation.top != m_allocation.top ) || ( oldallocation.left != m_allocation.left ) ) { HandlePositionChange(); HandleAbsolutePositionChange(); } if( ( oldallocation.width != m_allocation.width ) || ( oldallocation.height != m_allocation.height ) ) { HandleSizeChange(); Invalidate(); GetSignals().Emit( OnSizeAllocate ); } }
void ToggleFullscreen(HWND hWnd, bool goingFullscreen) { GraphicsContext *graphicsContext = PSP_CoreParameter().graphicsContext; // Make sure no rendering is happening during the switch. if (graphicsContext) { graphicsContext->Pause(); } WINDOWPLACEMENT placement = { sizeof(WINDOWPLACEMENT) }; GetWindowPlacement(hwndMain, &placement); int oldWindowState = g_WindowState; inFullscreenResize = true; g_IgnoreWM_SIZE = true; DWORD dwStyle; if (!goingFullscreen) { dwStyle = ::GetWindowLong(hWnd, GWL_STYLE); // Remove popup dwStyle &= ~WS_POPUP; // Re-add caption and border styles. dwStyle |= WS_OVERLAPPEDWINDOW; // Put back the menu bar. ::SetMenu(hWnd, menu); } else { // If the window was maximized before going fullscreen, make sure to restore first // in order not to have the taskbar show up on top of PPSSPP. if (oldWindowState == SIZE_MAXIMIZED || placement.showCmd == SW_SHOWMAXIMIZED) { ShowWindow(hwndMain, SW_RESTORE); } // Remove caption and border styles. dwStyle = ::GetWindowLong(hWnd, GWL_STYLE); dwStyle &= ~WS_OVERLAPPEDWINDOW; // Add Popup dwStyle |= WS_POPUP; } ::SetWindowLong(hWnd, GWL_STYLE, dwStyle); // Remove the menu bar. This can trigger WM_SIZE ::SetMenu(hWnd, goingFullscreen ? NULL : menu); g_Config.bFullScreen = goingFullscreen; g_IgnoreWM_SIZE = false; // Resize to the appropriate view. // If we're returning to window mode, re-apply the appropriate size setting. if (goingFullscreen) { if (g_Config.bFullScreenMulti) { // Maximize isn't enough to display on all monitors. // Remember that negative coordinates may be valid. int totalX = GetSystemMetrics(SM_XVIRTUALSCREEN); int totalY = GetSystemMetrics(SM_YVIRTUALSCREEN); int totalWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN); int totalHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN); MoveWindow(hwndMain, totalX, totalY, totalWidth, totalHeight, TRUE); HandleSizeChange(oldWindowState); } else { ShowWindow(hwndMain, SW_MAXIMIZE); } } else { ShowWindow(hwndMain, oldWindowState == SIZE_MAXIMIZED ? SW_MAXIMIZE : SW_RESTORE); if (g_Config.bFullScreenMulti && oldWindowState != SIZE_MAXIMIZED) { // Return the screen to where it was. MoveWindow(hwndMain, g_Config.iWindowX, g_Config.iWindowY, g_Config.iWindowWidth, g_Config.iWindowHeight, TRUE); } if (oldWindowState == SIZE_MAXIMIZED) { // WM_SIZE wasn't sent, since the size didn't change (it was full screen before and after.) HandleSizeChange(oldWindowState); } } inFullscreenResize = false; CorrectCursor(); ShowOwnedPopups(hwndMain, goingFullscreen ? FALSE : TRUE); W32Util::MakeTopMost(hwndMain, g_Config.bTopMost); WindowsRawInput::NotifyMenu(); if (graphicsContext) { graphicsContext->Resume(); } }
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: if (!DoesVersionMatchWindows(6, 0, 0, 0, true)) { // Remove the D3D11 choice on versions below XP RemoveMenu(GetMenu(hWnd), ID_OPTIONS_DIRECT3D11, MF_BYCOMMAND); } break; case WM_GETMINMAXINFO: { MINMAXINFO *minmax = reinterpret_cast<MINMAXINFO *>(lParam); RECT rc = { 0 }; bool portrait = g_Config.IsPortrait(); rc.right = portrait ? 272 : 480; rc.bottom = portrait ? 480 : 272; AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, TRUE); minmax->ptMinTrackSize.x = rc.right - rc.left; minmax->ptMinTrackSize.y = rc.bottom - rc.top; } return 0; case WM_ACTIVATE: { bool pause = true; if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE) { WindowsRawInput::GainFocus(); if (!IsIconic(GetHWND())) { InputDevice::GainFocus(); } g_activeWindow = WINDOW_MAINWINDOW; pause = false; } if (!noFocusPause && g_Config.bPauseOnLostFocus && GetUIState() == UISTATE_INGAME) { if (pause != Core_IsStepping()) { // != is xor for bools if (disasmWindow[0]) SendMessage(disasmWindow[0]->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0); else Core_EnableStepping(pause); } } if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE) { NativeMessageReceived("got_focus", ""); hasFocus = true; trapMouse = true; } if (wParam == WA_INACTIVE) { NativeMessageReceived("lost_focus", ""); WindowsRawInput::LoseFocus(); InputDevice::LoseFocus(); hasFocus = false; trapMouse = false; } } break; case WM_ERASEBKGND: // This window is always covered by DisplayWindow. No reason to erase. return 1; case WM_MOVE: SavePosition(); break; case WM_ENTERSIZEMOVE: inResizeMove = true; break; case WM_EXITSIZEMOVE: inResizeMove = false; HandleSizeChange(SIZE_RESTORED); break; case WM_SIZE: switch (wParam) { case SIZE_RESTORED: case SIZE_MAXIMIZED: if (g_IgnoreWM_SIZE) { return DefWindowProc(hWnd, message, wParam, lParam); } else if (!inResizeMove) { HandleSizeChange(wParam); } if (hasFocus) { InputDevice::GainFocus(); } break; case SIZE_MINIMIZED: Core_NotifyWindowHidden(true); if (!g_Config.bPauseWhenMinimized) { NativeMessageReceived("window minimized", "true"); } InputDevice::LoseFocus(); break; default: break; } break; case WM_TIMER: // Hack: Take the opportunity to also show/hide the mouse cursor in fullscreen mode. switch (wParam) { case TIMER_CURSORUPDATE: CorrectCursor(); return 0; case TIMER_CURSORMOVEUPDATE: hideCursor = true; KillTimer(hWnd, TIMER_CURSORMOVEUPDATE); return 0; } break; // For some reason, need to catch this here rather than in DisplayProc. case WM_MOUSEWHEEL: { int wheelDelta = (short)(wParam >> 16); KeyInput key; key.deviceId = DEVICE_ID_MOUSE; if (wheelDelta < 0) { key.keyCode = NKCODE_EXT_MOUSEWHEEL_DOWN; wheelDelta = -wheelDelta; } else { key.keyCode = NKCODE_EXT_MOUSEWHEEL_UP; } // There's no separate keyup event for mousewheel events, let's pass them both together. // This also means it really won't work great for key mapping :( Need to build a 1 frame delay or something. key.flags = KEY_DOWN | KEY_UP | KEY_HASWHEELDELTA | (wheelDelta << 16); NativeKey(key); } break; case WM_COMMAND: { if (!MainThread_Ready()) return DefWindowProc(hWnd, message, wParam, lParam); MainWindowMenu_Process(hWnd, wParam); } break; case WM_USER_TOGGLE_FULLSCREEN: ToggleFullscreen(hwndMain, wParam ? true : false); break; case WM_INPUT: return WindowsRawInput::Process(hWnd, wParam, lParam); // TODO: Could do something useful with WM_INPUT_DEVICE_CHANGE? // Not sure why we are actually getting WM_CHAR even though we use RawInput, but alright.. case WM_CHAR: return WindowsRawInput::ProcessChar(hWnd, wParam, lParam); case WM_DEVICECHANGE: #ifndef _M_ARM DinputDevice::CheckDevices(); #endif return DefWindowProc(hWnd, message, wParam, lParam); case WM_VERYSLEEPY_MSG: switch (wParam) { case VERYSLEEPY_WPARAM_SUPPORTED: return TRUE; case VERYSLEEPY_WPARAM_GETADDRINFO: { VerySleepy_AddrInfo *info = (VerySleepy_AddrInfo *)lParam; const u8 *ptr = (const u8 *)info->addr; std::string name; if (MIPSComp::jit && MIPSComp::jit->DescribeCodePtr(ptr, name)) { swprintf_s(info->name, L"Jit::%S", name.c_str()); return TRUE; } if (gpu && gpu->DescribeCodePtr(ptr, name)) { swprintf_s(info->name, L"GPU::%S", name.c_str()); return TRUE; } } return FALSE; default: return FALSE; } break; case WM_DROPFILES: { if (!MainThread_Ready()) return DefWindowProc(hWnd, message, wParam, lParam); HDROP hdrop = (HDROP)wParam; int count = DragQueryFile(hdrop,0xFFFFFFFF,0,0); if (count != 1) { MessageBox(hwndMain,L"You can only load one file at a time",L"Error",MB_ICONINFORMATION); } else { TCHAR filename[512]; if (DragQueryFile(hdrop, 0, filename, 512) != 0) { const std::string utf8_filename = ReplaceAll(ConvertWStringToUTF8(filename), "\\", "/"); NativeMessageReceived("boot", utf8_filename.c_str()); Core_EnableStepping(false); } } } break; case WM_CLOSE: InputDevice::StopPolling(); WindowsRawInput::Shutdown(); return DefWindowProc(hWnd,message,wParam,lParam); case WM_DESTROY: KillTimer(hWnd, TIMER_CURSORUPDATE); KillTimer(hWnd, TIMER_CURSORMOVEUPDATE); PostQuitMessage(0); break; case WM_USER + 1: if (disasmWindow[0]) disasmWindow[0]->NotifyMapLoaded(); if (memoryWindow[0]) memoryWindow[0]->NotifyMapLoaded(); if (disasmWindow[0]) disasmWindow[0]->UpdateDialog(); SetForegroundWindow(hwndMain); break; case WM_USER_SAVESTATE_FINISH: SetCursor(LoadCursor(0, IDC_ARROW)); break; case WM_USER_UPDATE_UI: TranslateMenus(hwndMain, menu); // Update checked status immediately for accelerators. UpdateMenus(); break; case WM_USER_WINDOW_TITLE_CHANGED: UpdateWindowTitle(); break; case WM_USER_BROWSE_BOOT_DONE: BrowseAndBootDone(); break; case WM_USER_BROWSE_BG_DONE: BrowseBackgroundDone(); break; case WM_USER_RESTART_EMUTHREAD: NativeSetRestarting(); InputDevice::StopPolling(); MainThread_Stop(); coreState = CORE_POWERUP; UpdateUIState(UISTATE_MENU); MainThread_Start(g_Config.iGPUBackend == (int)GPUBackend::OPENGL); InputDevice::BeginPolling(); break; case WM_MENUSELECT: // Called when a menu is opened. Also when an item is selected, but meh. UpdateMenus(true); WindowsRawInput::NotifyMenu(); trapMouse = false; break; case WM_EXITMENULOOP: // Called when menu is closed. trapMouse = true; break; // Turn off the screensaver. // Note that if there's a screensaver password, this simple method // doesn't work on Vista or higher. case WM_SYSCOMMAND: { switch (wParam) { case SC_SCREENSAVE: return 0; case SC_MONITORPOWER: return 0; } return DefWindowProc(hWnd, message, wParam, lParam); } default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
void ToggleFullscreen(HWND hWnd, bool goingFullscreen) { GraphicsContext *graphicsContext = PSP_CoreParameter().graphicsContext; // Make sure no rendering is happening during the switch. if (graphicsContext) { graphicsContext->Pause(); } int oldWindowState = g_WindowState; g_IgnoreWM_SIZE = true; DWORD dwStyle; if (!goingFullscreen) { dwStyle = ::GetWindowLong(hWnd, GWL_STYLE); // Remove popup dwStyle &= ~WS_POPUP; // Re-add caption and border styles. dwStyle |= WS_OVERLAPPEDWINDOW; // Put back the menu bar. ::SetMenu(hWnd, menu); } else { // If the window was maximized before going fullscreen, make sure to restore first // in order not to have the taskbar show up on top of PPSSPP. if (oldWindowState == SIZE_MAXIMIZED) { ShowWindow(hwndMain, SW_RESTORE); } // Remember the normal window rectangle. ::GetWindowRect(hWnd, &g_normalRC); // Remove caption and border styles. dwStyle = ::GetWindowLong(hWnd, GWL_STYLE); dwStyle &= ~WS_OVERLAPPEDWINDOW; // Add Popup dwStyle |= WS_POPUP; } ::SetWindowLong(hWnd, GWL_STYLE, dwStyle); // Remove the menu bar. This can trigger WM_SIZE ::SetMenu(hWnd, goingFullscreen ? NULL : menu); g_Config.bFullScreen = goingFullscreen; g_IgnoreWM_SIZE = false; // Resize to the appropriate view. // If we're returning to window mode, re-apply the appropriate size setting. if (goingFullscreen) { ShowWindow(hwndMain, SW_MAXIMIZE); } else { ShowWindow(hwndMain, oldWindowState == SIZE_MAXIMIZED ? SW_MAXIMIZE : SW_RESTORE); if (oldWindowState == SIZE_MAXIMIZED) { // WM_SIZE wasn't sent, since the size didn't change (it was full screen before and after.) HandleSizeChange(oldWindowState); } } CorrectCursor(); ShowOwnedPopups(hwndMain, goingFullscreen ? FALSE : TRUE); W32Util::MakeTopMost(hwndMain, g_Config.bTopMost); WindowsRawInput::NotifyMenu(); if (graphicsContext) { graphicsContext->Resume(); } }