diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/cru/base/Bitmask.h | 4 | ||||
-rw-r--r-- | include/cru/base/StringToNumberConverter.h | 10 | ||||
-rw-r--r-- | include/cru/platform/gui/Keyboard.h | 10 | ||||
-rw-r--r-- | include/cru/platform/gui/xcb/InputMethod.h | 77 | ||||
-rw-r--r-- | include/cru/platform/gui/xcb/UiApplication.h | 4 | ||||
-rw-r--r-- | include/cru/platform/gui/xcb/Window.h | 4 |
6 files changed, 98 insertions, 11 deletions
diff --git a/include/cru/base/Bitmask.h b/include/cru/base/Bitmask.h index 9b6b8957..7606f784 100644 --- a/include/cru/base/Bitmask.h +++ b/include/cru/base/Bitmask.h @@ -10,8 +10,10 @@ struct Bitmask final { constexpr Bitmask() : value(0) {} constexpr explicit Bitmask(TUnderlying value) : value(value) {} + // Start from 1. static constexpr Bitmask FromOffset(int offset) { - return Bitmask(static_cast<TUnderlying>(1u << offset)); + if (offset == 0) return {}; + return Bitmask(static_cast<TUnderlying>(1u << (offset - 1))); } constexpr bool Has(Bitmask rhs) const { return (value & rhs.value) != 0; } diff --git a/include/cru/base/StringToNumberConverter.h b/include/cru/base/StringToNumberConverter.h index 051f44d0..64c29971 100644 --- a/include/cru/base/StringToNumberConverter.h +++ b/include/cru/base/StringToNumberConverter.h @@ -14,15 +14,15 @@ using StringToNumberFlag = Bitmask<details::StringToNumberFlagTag>; struct StringToNumberFlags { constexpr static StringToNumberFlag kAllowLeadingSpaces = - StringToNumberFlag::FromOffset(0); - constexpr static StringToNumberFlag kAllowTrailingSpaces = StringToNumberFlag::FromOffset(1); - constexpr static StringToNumberFlag kAllowTrailingJunk = + constexpr static StringToNumberFlag kAllowTrailingSpaces = StringToNumberFlag::FromOffset(2); - constexpr static StringToNumberFlag kAllowLeadingZeroForInteger = + constexpr static StringToNumberFlag kAllowTrailingJunk = StringToNumberFlag::FromOffset(3); - constexpr static StringToNumberFlag kThrowOnError = + constexpr static StringToNumberFlag kAllowLeadingZeroForInteger = StringToNumberFlag::FromOffset(4); + constexpr static StringToNumberFlag kThrowOnError = + StringToNumberFlag::FromOffset(5); }; template <typename TResult> diff --git a/include/cru/platform/gui/Keyboard.h b/include/cru/platform/gui/Keyboard.h index eb1cc76e..97665e41 100644 --- a/include/cru/platform/gui/Keyboard.h +++ b/include/cru/platform/gui/Keyboard.h @@ -118,16 +118,16 @@ struct TagKeyModifier {}; using KeyModifier = Bitmask<details::TagKeyModifier>; struct KeyModifiers { - static constexpr KeyModifier none{0}; - static constexpr KeyModifier shift{0b1}; - static constexpr KeyModifier ctrl{0b10}; - static constexpr KeyModifier alt{0b100}; - static constexpr KeyModifier command{0b1000}; static constexpr KeyModifier None = KeyModifier::FromOffset(0); static constexpr KeyModifier Shift = KeyModifier::FromOffset(1); static constexpr KeyModifier Ctrl = KeyModifier::FromOffset(2); static constexpr KeyModifier Alt = KeyModifier::FromOffset(3); static constexpr KeyModifier Command = KeyModifier::FromOffset(4); + static constexpr KeyModifier none = None; + static constexpr KeyModifier shift = Shift; + static constexpr KeyModifier ctrl = Ctrl; + static constexpr KeyModifier alt = Alt; + static constexpr KeyModifier command = Command; }; #ifdef CRU_PLATFORM_OSX diff --git a/include/cru/platform/gui/xcb/InputMethod.h b/include/cru/platform/gui/xcb/InputMethod.h new file mode 100644 index 00000000..286f3158 --- /dev/null +++ b/include/cru/platform/gui/xcb/InputMethod.h @@ -0,0 +1,77 @@ +#pragma once + +#include "../InputMethod.h" +#include "Base.h" + +#include <xcb-imdkit/imclient.h> +#include <xcb/xcb.h> +#include <optional> + +namespace cru::platform::gui::xcb { +class XcbUiApplication; +class XcbWindow; + +class XcbXimInputMethodManager : public XcbResource { + friend XcbUiApplication; + + public: + XcbXimInputMethodManager(XcbUiApplication* application); + ~XcbXimInputMethodManager() override; + + xcb_xim_t* GetXcbXim(); + + private: + void DispatchCommit(xcb_xim_t* im, xcb_xic_t ic, std::string text); + void DispatchComposition(xcb_xim_t* im, xcb_xic_t ic, CompositionText text); + + bool HandleXEvent(xcb_generic_event_t* event); + + private: + XcbUiApplication* application_; + xcb_xim_t* im_; +}; + +class XcbXimInputMethodContext : public XcbResource, + public virtual IInputMethodContext { + friend XcbXimInputMethodManager; + + public: + XcbXimInputMethodContext(XcbXimInputMethodManager* manager, + XcbWindow* window); + ~XcbXimInputMethodContext() override; + + bool ShouldManuallyDrawCompositionText() override; + + void EnableIME() override; + void DisableIME() override; + + void CompleteComposition() override; + void CancelComposition() override; + CompositionText GetCompositionText() override; + + // Set the candidate window left-top. Relative to window left-top. Use this + // method to prepare typing. + void SetCandidateWindowPosition(const Point& point) override; + + IEvent<std::nullptr_t>* CompositionStartEvent() override; + IEvent<std::nullptr_t>* CompositionEndEvent() override; + IEvent<std::nullptr_t>* CompositionEvent() override; + IEvent<StringView>* TextEvent() override; + + private: + void CreateIc(xcb_window_t window); + void DestroyIc(); + + private: + XcbXimInputMethodManager* manager_; + XcbWindow* window_; + bool enabled_; + std::optional<xcb_xic_t> ic_; + CompositionText composition_text_; + + Event<std::nullptr_t> composition_start_event_; + Event<std::nullptr_t> composition_end_event_; + Event<std::nullptr_t> composition_event_; + Event<StringView> text_event_; +}; +} // namespace cru::platform::gui::xcb diff --git a/include/cru/platform/gui/xcb/UiApplication.h b/include/cru/platform/gui/xcb/UiApplication.h index b8de86f2..d6971099 100644 --- a/include/cru/platform/gui/xcb/UiApplication.h +++ b/include/cru/platform/gui/xcb/UiApplication.h @@ -13,6 +13,7 @@ namespace cru::platform::gui::xcb { class XcbWindow; class XcbCursorManager; +class XcbXimInputMethodManager; class XcbUiApplication : public XcbResource, public virtual IUiApplication { friend XcbWindow; @@ -49,6 +50,8 @@ class XcbUiApplication : public XcbResource, public virtual IUiApplication { #undef CRU_XCB_UI_APPLICATION_DEFINE_XCB_ATOM + XcbXimInputMethodManager* GetXcbXimInputMethodManager(); + public: int Run() override; @@ -100,5 +103,6 @@ class XcbUiApplication : public XcbResource, public virtual IUiApplication { std::vector<XcbWindow*> windows_; XcbCursorManager* cursor_manager_; + XcbXimInputMethodManager* input_method_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 61e4b616..e330ba7c 100644 --- a/include/cru/platform/gui/xcb/Window.h +++ b/include/cru/platform/gui/xcb/Window.h @@ -12,6 +12,7 @@ namespace cru::platform::gui::xcb { class XcbUiApplication; class XcbCursor; +class XcbXimInputMethodContext; class XcbWindow : public XcbResource, public virtual INativeWindow { friend XcbUiApplication; @@ -79,6 +80,8 @@ class XcbWindow : public XcbResource, public virtual INativeWindow { public: std::optional<xcb_window_t> GetXcbWindow(); + XcbUiApplication* GetXcbUiApplication(); + bool HasFocus(); private: xcb_window_t DoCreateWindow(); @@ -112,6 +115,7 @@ class XcbWindow : public XcbResource, public virtual INativeWindow { std::shared_ptr<XcbCursor> cursor_; XcbWindow* parent_; + XcbXimInputMethodContext* input_method_; Event<std::nullptr_t> create_event_; Event<std::nullptr_t> destroy_event_; |