diff options
Diffstat (limited to 'include/cru/platform/gui')
-rw-r--r-- | include/cru/platform/gui/Window.h | 3 | ||||
-rw-r--r-- | include/cru/platform/gui/xcb/Base.h | 4 | ||||
-rw-r--r-- | include/cru/platform/gui/xcb/Cursor.h | 44 | ||||
-rw-r--r-- | include/cru/platform/gui/xcb/UiApplication.h | 30 | ||||
-rw-r--r-- | include/cru/platform/gui/xcb/Window.h | 45 |
5 files changed, 87 insertions, 39 deletions
diff --git a/include/cru/platform/gui/Window.h b/include/cru/platform/gui/Window.h index 742ef798..885c1250 100644 --- a/include/cru/platform/gui/Window.h +++ b/include/cru/platform/gui/Window.h @@ -44,6 +44,7 @@ struct NativeKeyEventArgs { // Represents a native window, which exposes some low-level events and // operations. struct INativeWindow : virtual IPlatformResource { + virtual bool IsCreated(); virtual void Close() = 0; virtual INativeWindow* GetParent() = 0; @@ -72,6 +73,8 @@ struct INativeWindow : virtual IPlatformResource { // The lefttop of the rect is relative to screen lefttop. virtual void SetWindowRect(const Rect& rect) = 0; + // Return true if window gained the focus. But the return value should be + // ignored, since it does not guarantee anything. virtual bool RequestFocus() = 0; // Relative to client lefttop. diff --git a/include/cru/platform/gui/xcb/Base.h b/include/cru/platform/gui/xcb/Base.h index f3bcfd01..ad571a40 100644 --- a/include/cru/platform/gui/xcb/Base.h +++ b/include/cru/platform/gui/xcb/Base.h @@ -7,13 +7,13 @@ namespace cru::platform::gui::xcb { class XcbResource : public Object, public virtual IPlatformResource { public: - static String kPlatformId; + static constexpr const char16_t* kPlatformId = u"XCB"; protected: XcbResource() = default; public: - String GetPlatformId() const final { return kPlatformId; } + String GetPlatformId() const final { return String(kPlatformId); } }; class XcbException : public PlatformException { diff --git a/include/cru/platform/gui/xcb/Cursor.h b/include/cru/platform/gui/xcb/Cursor.h new file mode 100644 index 00000000..02ede7dd --- /dev/null +++ b/include/cru/platform/gui/xcb/Cursor.h @@ -0,0 +1,44 @@ +#pragma once + +#include <cru/base/io/Stream.h> +#include "../Cursor.h" +#include "Base.h" + +#include <xcb/xcb.h> +#include <xcb/xcb_cursor.h> +#include <memory> +#include <string_view> +#include <unordered_map> + +namespace cru::platform::gui::xcb { +class XcbUiApplication; + +class XcbCursor : public XcbResource, public virtual ICursor { + public: + XcbCursor(XcbUiApplication* application, xcb_cursor_t cursor, bool auto_free); + ~XcbCursor() override; + + xcb_cursor_t GetXcbCursor(); + + private: + XcbUiApplication* application_; + xcb_cursor_t cursor_; + bool auto_free_; +}; + +class XcbCursorManager : public XcbResource, public virtual ICursorManager { + public: + explicit XcbCursorManager(XcbUiApplication* application); + ~XcbCursorManager() override; + + std::shared_ptr<ICursor> GetSystemCursor(SystemCursorType type) override; + + private: + std::shared_ptr<XcbCursor> LoadXCursor(std::string_view name); + + private: + XcbUiApplication* application_; + xcb_cursor_context_t* xcb_cursor_context_; + std::unordered_map<SystemCursorType, std::shared_ptr<XcbCursor>> cursors_; +}; +} // namespace cru::platform::gui::xcb diff --git a/include/cru/platform/gui/xcb/UiApplication.h b/include/cru/platform/gui/xcb/UiApplication.h index 6063a8ab..b8de86f2 100644 --- a/include/cru/platform/gui/xcb/UiApplication.h +++ b/include/cru/platform/gui/xcb/UiApplication.h @@ -12,6 +12,7 @@ namespace cru::platform::gui::xcb { class XcbWindow; +class XcbCursorManager; class XcbUiApplication : public XcbResource, public virtual IUiApplication { friend XcbWindow; @@ -26,6 +27,7 @@ class XcbUiApplication : public XcbResource, public virtual IUiApplication { void CheckXcbConnectionError(); xcb_connection_t* GetXcbConnection(); + void XcbFlush(); // This API is weird, but before we have correct screen API, we still use it. xcb_screen_t* GetFirstXcbScreen(); @@ -41,6 +43,9 @@ class XcbUiApplication : public XcbResource, public virtual IUiApplication { CRU_XCB_UI_APPLICATION_DEFINE_XCB_ATOM(_NET_WM_WINDOW_TYPE) CRU_XCB_UI_APPLICATION_DEFINE_XCB_ATOM(_NET_WM_WINDOW_TYPE_NORMAL) CRU_XCB_UI_APPLICATION_DEFINE_XCB_ATOM(_NET_WM_WINDOW_TYPE_UTILITY) + CRU_XCB_UI_APPLICATION_DEFINE_XCB_ATOM(_NET_FRAME_EXTENTS) + CRU_XCB_UI_APPLICATION_DEFINE_XCB_ATOM(WM_PROTOCOLS) + CRU_XCB_UI_APPLICATION_DEFINE_XCB_ATOM(WM_DELETE_WINDOW) #undef CRU_XCB_UI_APPLICATION_DEFINE_XCB_ATOM @@ -61,29 +66,18 @@ class XcbUiApplication : public XcbResource, public virtual IUiApplication { std::function<void()> action) override; void CancelTimer(long long id) override; - virtual std::vector<INativeWindow*> GetAllWindow() = 0; + std::vector<INativeWindow*> GetAllWindow() override; - virtual INativeWindow* CreateWindow() = 0; + INativeWindow* CreateWindow() override; - virtual cru::platform::graphics::IGraphicsFactory* GetGraphicsFactory() = 0; + cru::platform::graphics::IGraphicsFactory* GetGraphicsFactory() override; - virtual ICursorManager* GetCursorManager() = 0; + ICursorManager* GetCursorManager() override; - virtual IClipboard* GetClipboard() = 0; + IClipboard* GetClipboard() override; // If return nullptr, it means the menu is not supported. - virtual IMenu* GetApplicationMenu(); - - /** - * \todo Implement on Windows. - */ - virtual std::optional<String> ShowSaveDialog(SaveDialogOptions options); - - /** - * \todo Implement on Windows. - */ - virtual std::optional<std::vector<String>> ShowOpenDialog( - OpenDialogOptions options); + IMenu* GetApplicationMenu() override; private: void HandleXEvents(); @@ -104,5 +98,7 @@ class XcbUiApplication : public XcbResource, public virtual IUiApplication { bool is_quit_on_all_window_closed_; std::vector<XcbWindow*> windows_; + + XcbCursorManager* cursor_manager_; }; } // namespace cru::platform::gui::xcb diff --git a/include/cru/platform/gui/xcb/Window.h b/include/cru/platform/gui/xcb/Window.h index 6d923666..61e4b616 100644 --- a/include/cru/platform/gui/xcb/Window.h +++ b/include/cru/platform/gui/xcb/Window.h @@ -1,5 +1,6 @@ #pragma once +#include "../../GraphicsBase.h" #include "../Window.h" #include "Base.h" @@ -10,6 +11,7 @@ namespace cru::platform::gui::xcb { class XcbUiApplication; +class XcbCursor; class XcbWindow : public XcbResource, public virtual INativeWindow { friend XcbUiApplication; @@ -18,6 +20,7 @@ class XcbWindow : public XcbResource, public virtual INativeWindow { explicit XcbWindow(XcbUiApplication* application); ~XcbWindow() override; + bool IsCreated() override; void Close() override; INativeWindow* GetParent() override; @@ -32,33 +35,27 @@ class XcbWindow : public XcbResource, public virtual INativeWindow { WindowVisibilityType GetVisibility() override; void SetVisibility(WindowVisibilityType visibility) override; - virtual Size GetClientSize() = 0; - virtual void SetClientSize(const Size& size) = 0; + Size GetClientSize() override; + void SetClientSize(const Size& size) override; - virtual Rect GetClientRect() = 0; - virtual void SetClientRect(const Rect& rect) = 0; + Rect GetClientRect() override; + void SetClientRect(const Rect& rect) override; - // Get the rect of the window containing frame. - // The lefttop of the rect is relative to screen lefttop. - virtual Rect GetWindowRect() = 0; + Rect GetWindowRect() override; + void SetWindowRect(const Rect& rect) override; - // Set the rect of the window containing frame. - // The lefttop of the rect is relative to screen lefttop. - virtual void SetWindowRect(const Rect& rect) = 0; + bool RequestFocus() override; - virtual bool RequestFocus() = 0; + Point GetMousePosition() override; - // Relative to client lefttop. - virtual Point GetMousePosition() = 0; + bool CaptureMouse() override; + bool ReleaseMouse() override; - virtual bool CaptureMouse() = 0; - virtual bool ReleaseMouse() = 0; + void SetCursor(std::shared_ptr<ICursor> cursor) override; - virtual void SetCursor(std::shared_ptr<ICursor> cursor) = 0; + void SetToForeground() override; - virtual void SetToForeground() = 0; - - virtual void RequestRepaint() = 0; + void RequestRepaint() override; std::unique_ptr<graphics::IPainter> BeginPaint() override; @@ -78,7 +75,7 @@ class XcbWindow : public XcbResource, public virtual INativeWindow { IEvent<NativeKeyEventArgs>* KeyDownEvent() override; IEvent<NativeKeyEventArgs>* KeyUpEvent() override; - virtual IInputMethodContext* GetInputMethodContext() = 0; + IInputMethodContext* GetInputMethodContext() override; public: std::optional<xcb_window_t> GetXcbWindow(); @@ -91,12 +88,19 @@ class XcbWindow : public XcbResource, public virtual INativeWindow { void DoSetParent(xcb_window_t window); void DoSetStyleFlags(xcb_window_t window); void DoSetTitle(xcb_window_t window); + void DoSetClientRect(xcb_window_t window, const Rect& rect); + void DoSetCursor(xcb_window_t window, XcbCursor* cursor); void* XcbGetProperty(xcb_window_t window, xcb_atom_t property, xcb_atom_t type, std::uint32_t offset, std::uint32_t length, std::uint32_t* out_length = nullptr); + // Relative to screen lefttop. + Point GetXcbWindowPosition(xcb_window_t window); + + std::optional<Thickness> Get_NET_FRAME_EXTENTS(xcb_window_t window); + private: XcbUiApplication* application_; std::optional<xcb_window_t> xcb_window_; @@ -105,6 +109,7 @@ class XcbWindow : public XcbResource, public virtual INativeWindow { WindowStyleFlag style_; std::string title_; bool mapped_; + std::shared_ptr<XcbCursor> cursor_; XcbWindow* parent_; |