diff --git a/examples/helloworld.cpp b/examples/helloworld.cpp index dc05fbcb7..42c93cb7c 100644 --- a/examples/helloworld.cpp +++ b/examples/helloworld.cpp @@ -1,5 +1,5 @@ // LAF Library -// Copyright (c) 2019-2020 Igara Studio S.A. +// Copyright (c) 2019-2021 Igara Studio S.A. // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -39,6 +39,7 @@ int app_main(int argc, char* argv[]) display->setNativeMouseCursor(os::kArrowCursor); display->setTitle("Hello World"); + display->handleResize = draw_display; // On macOS: With finishLaunching() we start processing // NSApplicationDelegate events. After calling this we'll start @@ -92,6 +93,12 @@ int app_main(int argc, char* argv[]) display->setScale(1 + (int)(ev.scancode() - os::kKey1)); redraw = true; break; + + case os::kKeyF: + case os::kKeyF11: + display->setFullscreen(!display->isFullscreen()); + break; + default: // Do nothing break; diff --git a/os/CMakeLists.txt b/os/CMakeLists.txt index b63cfadbe..ab13265b8 100644 --- a/os/CMakeLists.txt +++ b/os/CMakeLists.txt @@ -59,7 +59,6 @@ if(LAF_BACKEND STREQUAL "skia") endif() list(APPEND LAF_OS_SOURCES skia/os.cpp - skia/resize_surface.cpp skia/skia_color_space.cpp skia/skia_display.cpp skia/skia_draw_text.cpp diff --git a/os/common/event_queue_with_resize_display.h b/os/common/event_queue_with_resize_display.h deleted file mode 100644 index d6553b151..000000000 --- a/os/common/event_queue_with_resize_display.h +++ /dev/null @@ -1,91 +0,0 @@ -// LAF OS Library -// Copyright (C) 2019 Igara Studio S.A. -// Copyright (C) 2018 David Capello -// -// This file is released under the terms of the MIT license. -// Read LICENSE.txt for more information. - -#ifndef OS_COMMON_EVENT_QUEUE_WITH_RESIZE_DISPLAY_INCLUDED -#define OS_COMMON_EVENT_QUEUE_WITH_RESIZE_DISPLAY_INCLUDED -#pragma once - -#include "base/time.h" -#include "os/event.h" -#include "os/event_queue.h" - -#include - -namespace os { - -#pragma push_macro("None") -#undef None // Undefine the X11 None macro - -// Auxiliary class to handle the ResizeDisplay event in a special way. -// We can use the setResizeDisplayEvent() function in this class to -// change a pending resize event to be sent in a near future (after -// 100ms). If we receive other setResizeDisplayEvent() calls, only -// one ResizeEvent will be generated (the last one). -// -// This class is useful in platforms like X11 where we cannot know -// when the resize operation has started and finished with information -// from the OS. We only receive a sequence of ConfigureNotify events, -// but we never know when it's the last resize event (we can guess -// that is the last resize event when queueEvent() is called with a -// non-Event::None kind of event). -// -// On Windows, we use this event queue behavior just in case we don't -// receive a WM_EXITSIZEMOVE message (I don't have information if this -// can happen, but the timer might be a good solution just in case we -// don't receive the message). -class EventQueueWithResizeDisplay : public EventQueue { -public: - // This should be called at the beginning of getEvent() member. - void checkResizeDisplayEvent(bool& canWait) { - if (m_resizeEvent.type() != Event::None) { - canWait = false; - // Wait 100ms to enqueue the event - if (base::current_tick() - m_resizeEventTick > 100) - enqueueResizeDisplayEvent(); - } - } - - void queueEvent(const Event& ev) override { - // If we are enqueuing another event and we have a pending - // ResizeDisplay event, we first enqueue the ResizeDisplay event, - // because it means that the resize operation is over. - if (m_resizeEvent.type() != Event::None) - enqueueResizeDisplayEvent(); - m_events.push(ev); - } - - // Sets the ResizeDisplay to be sent in the near time (150ms in the - // future). This is used to avoid sending a lot of ResizeDisplay - // events while the user is resizing the window. - // - // Returns true if this is the first ResizeDisplay event of a - // sequence of resize events. - bool setResizeDisplayEvent(const Event& resizeEvent) { - bool isNewEvent = (m_resizeEvent.type() == Event::None); - m_resizeEvent = resizeEvent; - m_resizeEventTick = base::current_tick(); - return isNewEvent; - } - - void enqueueResizeDisplayEvent() { - m_events.push(m_resizeEvent); - m_resizeEvent.setType(Event::None); - m_resizeEventTick = 0; - } - -protected: - std::queue m_events; - - Event m_resizeEvent; - base::tick_t m_resizeEventTick = 0; -}; - -#pragma pop_macro("None") - -} // namespace os - -#endif diff --git a/os/display.h b/os/display.h index 3b236ad42..9e357996c 100644 --- a/os/display.h +++ b/os/display.h @@ -1,5 +1,5 @@ // LAF OS Library -// Copyright (c) 2018-2020 Igara Studio S.A. +// Copyright (c) 2018-2021 Igara Studio S.A. // Copyright (c) 2012-2018 David Capello // // This file is released under the terms of the MIT license. @@ -15,6 +15,7 @@ #include "os/ref.h" #include "os/surface_list.h" +#include #include namespace os { @@ -30,6 +31,14 @@ namespace os { virtual ~Display() { } + // Function called to handle a "live resize"/resizing loop. If + // this is nullptr, an Event::ResizeDisplay is generated when the + // resizing is finished. + // + // TODO I think we should have a DisplayDelegate for this instead + // of a public property. + std::function handleResize = nullptr; + // Returns the real and current display's size (without scale applied). virtual int width() const = 0; virtual int height() const = 0; diff --git a/os/osx/window.h b/os/osx/window.h index e46ec0817..e8803a03a 100644 --- a/os/osx/window.h +++ b/os/osx/window.h @@ -1,5 +1,5 @@ // LAF OS Library -// Copyright (C) 2018-2020 Igara Studio S.A. +// Copyright (C) 2018-2021 Igara Studio S.A. // Copyright (C) 2012-2017 David Capello // // This file is released under the terms of the MIT license. @@ -36,6 +36,7 @@ class OSXWindowImpl { virtual void onDrawRect(const gfx::Rect& rect) = 0; virtual void onWindowChanged() = 0; virtual void onStartResizing() = 0; + virtual void onResizing(gfx::Size& size) = 0; virtual void onEndResizing() = 0; // This generally happens when the window is moved to another diff --git a/os/osx/window.mm b/os/osx/window.mm index 0ccf9faa7..e04b87e10 100644 --- a/os/osx/window.mm +++ b/os/osx/window.mm @@ -1,5 +1,5 @@ // LAF OS Library -// Copyright (C) 2020 Igara Studio S.A. +// Copyright (C) 2019-2020 Igara Studio S.A. // Copyright (C) 2012-2017 David Capello // // This file is released under the terms of the MIT license. @@ -51,6 +51,10 @@ - (OSXWindow*)initWithImpl:(OSXWindowImpl*)impl OSXView* view = [[OSXView alloc] initWithFrame:rect]; [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + // Redraw the entire window content when we resize it. + // TODO add support to avoid redrawing the entire window + self.preservesContentDuringLiveResize = false; + [self setDelegate:m_delegate]; [self setContentView:view]; [self center]; diff --git a/os/osx/window_delegate.h b/os/osx/window_delegate.h index 99c319992..a406694fa 100644 --- a/os/osx/window_delegate.h +++ b/os/osx/window_delegate.h @@ -1,5 +1,5 @@ // LAF OS Library -// Copyright (C) 2020 Igara Studio S.A. +// Copyright (C) 2020-2021 Igara Studio S.A. // Copyright (C) 2015 David Capello // // This file is released under the terms of the MIT license. @@ -41,6 +41,15 @@ class OSXWindowImpl; m_impl->onStartResizing(); } +- (NSSize)windowWillResize:(NSWindow*)sender + toSize:(NSSize)frameSize +{ + NSView* view = sender.contentView; + gfx::Size sz(view.bounds.size.width, view.bounds.size.height); + m_impl->onResizing(sz); + return frameSize; +} + - (void)windowDidEndLiveResize:(NSNotification*)notification { m_impl->onEndResizing(); diff --git a/os/skia/resize_surface.cpp b/os/skia/resize_surface.cpp deleted file mode 100644 index 2ff9cc631..000000000 --- a/os/skia/resize_surface.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// LAF OS Library -// Copyright (c) 2018-2020 Igara Studio S.A. -// Copyright (C) 2018 David Capello -// -// This file is released under the terms of the MIT license. -// Read LICENSE.txt for more information. - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "os/skia/resize_surface.h" - -namespace os { - -ResizeSurface::ResizeSurface() - : m_snapshot(nullptr) -{ -} - -ResizeSurface::~ResizeSurface() -{ - reset(); -} - -void ResizeSurface::make(Display* display) -{ - if (m_snapshot) - m_snapshot.reset(); - - auto surface = static_cast(display->surface()); - ASSERT(surface); - if (!surface) - return; - - // Sometimes on X11 when the window is just created, the display - // surface can have width == 0. So there is no need to create a - // snapshot of the recently created window in this case. - if (surface->width() == 0 || - surface->height() == 0) - return; - - m_snapshot = make_ref(); - m_snapshot->create(surface->width(), - surface->height(), - surface->colorSpace()); - m_snapshot->drawSurface(surface, 0, 0); -} - -void ResizeSurface::reset() -{ - if (!m_snapshot) - return; - m_snapshot.reset(); -} - -void ResizeSurface::draw(Display* display) -{ - if (!m_snapshot) - return; - - auto surface = static_cast(display->surface()); - ASSERT(surface); - if (!surface) - return; - - surface->drawSurface( - m_snapshot.get(), - gfx::Rect(0, 0, m_snapshot->width(), m_snapshot->height()), - gfx::Rect(0, 0, surface->width(), surface->height())); -} - -} // namespace os diff --git a/os/skia/resize_surface.h b/os/skia/resize_surface.h deleted file mode 100644 index 7befb16e7..000000000 --- a/os/skia/resize_surface.h +++ /dev/null @@ -1,37 +0,0 @@ -// LAF OS Library -// Copyright (C) 2020 Igara Studio S.A. -// Copyright (C) 2018 David Capello -// -// This file is released under the terms of the MIT license. -// Read LICENSE.txt for more information. - -#ifndef OS_SKIA_RESIZE_SURFACE_INCLUDED -#define OS_SKIA_RESIZE_SURFACE_INCLUDED -#pragma once - -#include "os/display.h" -#include "os/skia/skia_surface.h" - -namespace os { - -class ResizeSurface { -public: - ResizeSurface(); - ~ResizeSurface(); - - ResizeSurface(const ResizeSurface&) = delete; - ResizeSurface& operator=(const ResizeSurface&) = delete; - - void make(Display* display); - void reset(); - void draw(Display* display); - - operator bool() { return m_snapshot != nullptr; } - -private: - Ref m_snapshot; -}; - -} // namespace os - -#endif diff --git a/os/skia/skia_display.cpp b/os/skia/skia_display.cpp index 726b82a0a..06137e3a8 100644 --- a/os/skia/skia_display.cpp +++ b/os/skia/skia_display.cpp @@ -1,5 +1,5 @@ // LAF OS Library -// Copyright (c) 2018-2020 Igara Studio S.A. +// Copyright (C) 2018-2021 Igara Studio S.A. // Copyright (C) 2012-2018 David Capello // // This file is released under the terms of the MIT license. @@ -46,16 +46,18 @@ void SkiaDisplay::resetSkiaSurface() m_surface = nullptr; m_customSurface = false; - resize(m_window.clientSize()); + resizeSkiaSurface(m_window.clientSize()); } -void SkiaDisplay::resize(const gfx::Size& size) +void SkiaDisplay::resizeSkiaSurface(const gfx::Size& size) { if (!m_initialized || m_customSurface) return; gfx::Size newSize(size.w / m_window.scale(), size.h / m_window.scale()); + newSize.w = std::max(1, newSize.w); + newSize.h = std::max(1, newSize.h); if (m_initialized && m_surface && @@ -138,19 +140,6 @@ void SkiaDisplay::setFullscreen(bool state) m_window.setFullscreen(state); } -void SkiaDisplay::resetSurfaceAndQueueResizeDisplayEvent() -{ - // Redraw the full skia surface - if (m_surface) - resetSkiaSurface(); - - // Generate the resizing display event to redraw everything. - Event ev; - ev.setType(Event::ResizeDisplay); - ev.setDisplay(this); - os::queue_event(ev); -} - void SkiaDisplay::setTitle(const std::string& title) { m_window.setTitle(title); diff --git a/os/skia/skia_display.h b/os/skia/skia_display.h index a4c43eb3a..381bd13e2 100644 --- a/os/skia/skia_display.h +++ b/os/skia/skia_display.h @@ -25,6 +25,7 @@ class SkiaDisplay : public Display { bool isInitialized() const { return m_initialized; } void setSkiaSurface(SkiaSurface* surface); void resetSkiaSurface(); + void resizeSkiaSurface(const gfx::Size& size); void resize(const gfx::Size& size); @@ -74,8 +75,6 @@ class SkiaDisplay : public Display { void setColorSpace(const os::ColorSpaceRef& colorSpace); os::ColorSpaceRef currentMonitorColorSpace() const; - void resetSurfaceAndQueueResizeDisplayEvent(); - void onTabletAPIChange(); // Returns the HWND on Windows. diff --git a/os/skia/skia_window_osx.mm b/os/skia/skia_window_osx.mm index 1042e2962..6aabbd3f5 100644 --- a/os/skia/skia_window_osx.mm +++ b/os/skia/skia_window_osx.mm @@ -1,5 +1,5 @@ // LAF OS Library -// Copyright (C) 2018-2020 Igara Studio S.A. +// Copyright (C) 2018-2021 Igara Studio S.A. // Copyright (C) 2012-2018 David Capello // // This file is released under the terms of the MIT license. @@ -22,7 +22,6 @@ #include "os/osx/event_queue.h" #include "os/osx/view.h" #include "os/osx/window.h" -#include "os/skia/resize_surface.h" #include "os/skia/skia_color_space.h" #include "os/skia/skia_display.h" #include "os/skia/skia_surface.h" @@ -267,15 +266,17 @@ void onResize(const gfx::Size& size) override { createRenderTarget(size); #endif - m_display->resize(size); - if (m_resizeSurface) { - m_resizeSurface.draw(m_display); - if (m_backend == Backend::GL) - invalidateRegion(gfx::Region(gfx::Rect(size))); - } + m_display->resizeSkiaSurface(size); + if (m_backend == Backend::GL) + invalidateRegion(gfx::Region(gfx::Rect(size))); } void onDrawRect(const gfx::Rect& rect) override { + if (m_window.contentView.inLiveResize) { + if (m_display->handleResize) + m_display->handleResize(m_display); + } + switch (m_backend) { case Backend::NONE: @@ -300,20 +301,26 @@ void onWindowChanged() override { void onStartResizing() override { if (++m_resizingCount > 1) return; + } - ASSERT(!m_resizeSurface); - m_resizeSurface.make(m_display); + void onResizing(gfx::Size& size) override { + m_display->resizeSkiaSurface(size); + if (m_display->handleResize) { + m_display->handleResize(m_display); + } } void onEndResizing() override { if (--m_resizingCount > 0) return; - ASSERT(m_resizeSurface); - m_resizeSurface.reset(); - // Generate the resizing display event for the user. - m_display->resetSurfaceAndQueueResizeDisplayEvent(); + if (!m_display->handleResize) { + Event ev; + ev.setType(Event::ResizeDisplay); + ev.setDisplay(m_display); + os::queue_event(ev); + } } void onChangeBackingProperties() override { @@ -562,8 +569,6 @@ void paintGC(const gfx::Rect& rect) { // and windowWill/DidStart/EndLiveResize notifications. int m_resizingCount = 0; - // Surface used for live resizing. - ResizeSurface m_resizeSurface; #if SK_SUPPORT_GPU sk_sp m_glInterfaces; diff --git a/os/skia/skia_window_win.cpp b/os/skia/skia_window_win.cpp index 060d9bcc8..31e6436c5 100644 --- a/os/skia/skia_window_win.cpp +++ b/os/skia/skia_window_win.cpp @@ -1,5 +1,5 @@ // LAF OS Library -// Copyright (C) 2019-2020 Igara Studio S.A. +// Copyright (C) 2019-2021 Igara Studio S.A. // Copyright (C) 2012-2018 David Capello // // This file is released under the terms of the MIT license. @@ -12,7 +12,6 @@ #include "os/skia/skia_window_win.h" #include "base/log.h" -#include "os/common/event_queue_with_resize_display.h" #include "os/event.h" #include "os/event_queue.h" #include "os/skia/skia_display.h" @@ -359,27 +358,30 @@ void SkiaWindow::onResize(const gfx::Size& size) // TODO the next code is quite similar to SkiaWindow::onResize() for X11. - // Set the ResizeDisplay event that will be sent in the near time - // (150ms) by the EventQueueWithResizeDisplay. - Event ev; - ev.setType(Event::ResizeDisplay); - ev.setDisplay(m_display); - const bool isNewEvent = - static_cast(EventQueue::instance()) - ->setResizeDisplayEvent(ev); + m_display->resizeSkiaSurface(size); + if (m_display->handleResize) + m_display->handleResize(m_display); + else if (!m_resizing) { + Event ev; + ev.setType(Event::ResizeDisplay); + ev.setDisplay(m_display); + queue_event(ev); + } +} - if (isNewEvent) m_resizeSurface.make(m_display); - m_display->resize(size); - if (!isNewEvent) m_resizeSurface.draw(m_display); +void SkiaWindow::onStartResizing() +{ + m_resizing = true; } void SkiaWindow::onEndResizing() { - m_resizeSurface.reset(); + m_resizing = false; - // Force the ResizeDisplay event now. - static_cast(EventQueue::instance()) - ->enqueueResizeDisplayEvent(); + Event ev; + ev.setType(Event::ResizeDisplay); + ev.setDisplay(m_display); + queue_event(ev); } void SkiaWindow::onChangeColorSpace() diff --git a/os/skia/skia_window_win.h b/os/skia/skia_window_win.h index e3234e1a8..e08ee715b 100644 --- a/os/skia/skia_window_win.h +++ b/os/skia/skia_window_win.h @@ -1,4 +1,5 @@ // LAF OS Library +// Copyright (C) 2021 Igara Studio S.A. // Copyright (C) 2012-2018 David Capello // // This file is released under the terms of the MIT license. @@ -9,7 +10,6 @@ #pragma once #include "base/disable_copying.h" -#include "os/skia/resize_surface.h" #include "os/skia/skia_surface.h" #include "os/win/window.h" @@ -35,6 +35,7 @@ class SkiaWindow : public WinWindow { void onQueueEvent(Event& ev) override; void onPaint(HDC hdc) override; void onResize(const gfx::Size& sz) override; + void onStartResizing() override; void onEndResizing() override; void onChangeColorSpace() override; void paintHDC(HDC dc); @@ -50,8 +51,8 @@ class SkiaWindow : public WinWindow { EventQueue* m_queue; SkiaDisplay* m_display; - ResizeSurface m_resizeSurface; Backend m_backend; + bool m_resizing = false; #if SK_SUPPORT_GPU std::unique_ptr m_glCtx; sk_sp m_glInterfaces; diff --git a/os/skia/skia_window_x11.cpp b/os/skia/skia_window_x11.cpp index 476edd334..af8e2201d 100644 --- a/os/skia/skia_window_x11.cpp +++ b/os/skia/skia_window_x11.cpp @@ -1,5 +1,5 @@ // LAF OS Library -// Copyright (C) 2020 Igara Studio S.A. +// Copyright (C) 2020-2021 Igara Studio S.A. // Copyright (C) 2016-2018 David Capello // // This file is released under the terms of the MIT license. @@ -12,7 +12,6 @@ #include "os/skia/skia_window_x11.h" #include "gfx/size.h" -#include "os/common/event_queue_with_resize_display.h" #include "os/event.h" #include "os/event_queue.h" #include "os/skia/skia_display.h" @@ -137,18 +136,15 @@ void SkiaWindow::onPaint(const gfx::Rect& rc) void SkiaWindow::onResize(const gfx::Size& sz) { - // Set the ResizeDisplay event that will be sent in the near time - // (150ms) by the EventQueueWithResizeDisplay. - Event ev; - ev.setType(Event::ResizeDisplay); - ev.setDisplay(m_display); - const bool isNewEvent = - static_cast(EventQueue::instance()) - ->setResizeDisplayEvent(ev); - - if (isNewEvent) m_resizeSurface.make(m_display); - m_display->resize(sz); - if (!isNewEvent) m_resizeSurface.draw(m_display); + m_display->resizeSkiaSurface(sz); + if (m_display->handleResize) + m_display->handleResize(m_display); + else { + Event ev; + ev.setType(Event::ResizeDisplay); + ev.setDisplay(m_display); + queue_event(ev); + } } } // namespace os diff --git a/os/skia/skia_window_x11.h b/os/skia/skia_window_x11.h index de77cf74f..4b2733ec8 100644 --- a/os/skia/skia_window_x11.h +++ b/os/skia/skia_window_x11.h @@ -1,4 +1,5 @@ // LAF OS Library +// Copyright (C) 2021 Igara Studio S.A. // Copyright (C) 2016-2018 David Capello // // This file is released under the terms of the MIT license. @@ -11,7 +12,6 @@ #include "base/disable_copying.h" #include "gfx/size.h" #include "os/native_cursor.h" -#include "os/skia/resize_surface.h" #include "os/x11/window.h" #include @@ -45,7 +45,6 @@ class SkiaWindow : public X11Window { EventQueue* m_queue; SkiaDisplay* m_display; - ResizeSurface m_resizeSurface; std::vector m_buffer; DISABLE_COPYING(SkiaWindow); diff --git a/os/win/event_queue.cpp b/os/win/event_queue.cpp index 63cbb79fe..a1f26e03b 100644 --- a/os/win/event_queue.cpp +++ b/os/win/event_queue.cpp @@ -17,6 +17,11 @@ namespace os { +void WinEventQueue::queueEvent(const Event& ev) +{ + m_events.push(ev); +} + void WinEventQueue::getEvent(Event& ev, bool canWait) { MSG msg; @@ -24,8 +29,6 @@ void WinEventQueue::getEvent(Event& ev, bool canWait) while (m_events.empty()) { BOOL res; - checkResizeDisplayEvent(canWait); - if (canWait) { res = GetMessage(&msg, nullptr, 0, 0); } diff --git a/os/win/event_queue.h b/os/win/event_queue.h index c9b9aea6f..ad5d6dbf0 100644 --- a/os/win/event_queue.h +++ b/os/win/event_queue.h @@ -1,5 +1,5 @@ // LAF OS Library -// Copyright (C) 2020 Igara Studio S.A. +// Copyright (C) 2020-2021 Igara Studio S.A. // Copyright (C) 2012-2018 David Capello // // This file is released under the terms of the MIT license. @@ -9,13 +9,20 @@ #define OS_WIN_EVENT_QUEUE_INCLUDED #pragma once -#include "os/common/event_queue_with_resize_display.h" +#include "os/event.h" +#include "os/event_queue.h" + +#include namespace os { -class WinEventQueue : public EventQueueWithResizeDisplay { +class WinEventQueue : public EventQueue { public: + void queueEvent(const Event& ev) override; void getEvent(Event& ev, bool canWait) override; + +private: + std::queue m_events; }; using EventQueueImpl = WinEventQueue; diff --git a/os/win/window.cpp b/os/win/window.cpp index 31a2c1a2a..6b864a180 100644 --- a/os/win/window.cpp +++ b/os/win/window.cpp @@ -1,5 +1,5 @@ // LAF OS Library -// Copyright (C) 2018-2020 Igara Studio S.A. +// Copyright (C) 2018-2021 Igara Studio S.A. // Copyright (C) 2012-2018 David Capello // // This file is released under the terms of the MIT license. @@ -332,10 +332,19 @@ void WinWindow::setFullscreen(bool state) if (!GetMonitorInfoA(monitor, &mi)) return; // Invalid monitor info? - // Save the current window position to restore it when we exit the - // full screen mode. + // Save the current window frame position to restore it when we + // exit the full screen mode. +#if 0 m_restoredPlacement.length = sizeof(WINDOWPLACEMENT); GetWindowPlacement(m_hwnd, &m_restoredPlacement); +#else + { + RECT rc; + GetWindowRect(m_hwnd, &rc); + m_restoredFrame = gfx::Rect(rc.left, rc.top, + rc.right - rc.left, rc.bottom - rc.top); + } +#endif LONG style = GetWindowLong(m_hwnd, GWL_STYLE); style &= ~(WS_CAPTION | WS_THICKFRAME); @@ -346,14 +355,23 @@ void WinWindow::setFullscreen(bool state) (mi.rcMonitor.right - mi.rcMonitor.left), (mi.rcMonitor.bottom - mi.rcMonitor.top), SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); - } // Exit from full screen mode else if (currentFullscreen && !state) { LONG style = GetWindowLong(m_hwnd, GWL_STYLE); style |= WS_CAPTION | WS_THICKFRAME; SetWindowLong(m_hwnd, GWL_STYLE, style); + + // On restore, resize to the previous saved rect size. +#if 0 SetWindowPlacement(m_hwnd, &m_restoredPlacement); +#else + SetWindowPos(m_hwnd, nullptr, + m_restoredFrame.x, m_restoredFrame.y, + m_restoredFrame.w, m_restoredFrame.h, + SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); +#endif + onResize(m_clientSize); } } diff --git a/os/win/window.h b/os/win/window.h index 2d4213433..292b1ea60 100644 --- a/os/win/window.h +++ b/os/win/window.h @@ -1,5 +1,5 @@ // LAF OS Library -// Copyright (C) 2018-2020 Igara Studio S.A. +// Copyright (C) 2018-2021 Igara Studio S.A. // Copyright (C) 2012-2018 David Capello // // This file is released under the terms of the MIT license. @@ -85,6 +85,7 @@ namespace os { virtual void onQueueEvent(Event& ev) { } virtual void onResize(const gfx::Size& sz) { } virtual void onStartResizing() { } + virtual void onResizing(gfx::Size& sz) { } virtual void onEndResizing() { } virtual void onPaint(HDC hdc) { } virtual void onChangeColorSpace() { } @@ -106,7 +107,13 @@ namespace os { // Used to store the current window position before toggling on // full-screen mode. +#if 0 + // TODO Restoring WINDOWPLACEMENT doesn't work well when the + // window is maximixed. WINDOWPLACEMENT m_restoredPlacement; +#else + gfx::Rect m_restoredFrame; +#endif int m_scale; bool m_isCreated; diff --git a/os/x11/event_queue.cpp b/os/x11/event_queue.cpp index 8eb86a3b4..9bb6ae294 100644 --- a/os/x11/event_queue.cpp +++ b/os/x11/event_queue.cpp @@ -1,5 +1,5 @@ // LAF OS Library -// Copyright (C) 2019 Igara Studio S.A. +// Copyright (C) 2019-2021 Igara Studio S.A. // Copyright (C) 2016-2018 David Capello // // This file is released under the terms of the MIT license. @@ -66,10 +66,13 @@ const char* get_event_name(XEvent& event) } // anonymous namespace #endif -void X11EventQueue::getEvent(Event& ev, bool canWait) +void X11EventQueue::queueEvent(const Event& ev) { - checkResizeDisplayEvent(canWait); + m_events.push(ev); +} +void X11EventQueue::getEvent(Event& ev, bool canWait) +{ ::Display* display = X11::instance()->display(); XSync(display, False); diff --git a/os/x11/event_queue.h b/os/x11/event_queue.h index 2c78aab31..6ef249254 100644 --- a/os/x11/event_queue.h +++ b/os/x11/event_queue.h @@ -1,4 +1,5 @@ // LAF OS Library +// Copyright (C) 2021 Igara Studio S.A. // Copyright (C) 2016-2018 David Capello // // This file is released under the terms of the MIT license. @@ -8,19 +9,22 @@ #define OS_X11_EVENT_QUEUE_INCLUDED #pragma once -#include "os/common/event_queue_with_resize_display.h" +#include "os/event_queue.h" #include "os/x11/x11.h" #include namespace os { -class X11EventQueue : public EventQueueWithResizeDisplay { +class X11EventQueue : public EventQueue { public: + void queueEvent(const Event& ev) override; void getEvent(Event& ev, bool canWait) override; private: void processX11Event(XEvent& event); + + std::queue m_events; }; typedef X11EventQueue EventQueueImpl;