| // Copyright 2013 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef UI_LINUX_LINUX_UI_H_ |
| #define UI_LINUX_LINUX_UI_H_ |
| |
| #include <memory> |
| #include <optional> |
| #include <string> |
| #include <vector> |
| |
| #include "base/command_line.h" |
| #include "base/component_export.h" |
| #include "base/containers/flat_map.h" |
| #include "base/observer_list.h" |
| #include "base/scoped_observation_traits.h" |
| #include "build/buildflag.h" |
| #include "build/chromecast_buildflags.h" |
| #include "printing/buildflags/buildflags.h" |
| #include "ui/display/types/display_config.h" |
| |
| // The main entrypoint into Linux toolkit specific code. GTK/QT code should only |
| // be executed behind this interface. |
| |
| using SkColor = uint32_t; |
| // TODO(thomasanderson): Remove Profile forward declaration. |
| class Profile; |
| |
| namespace aura { |
| class Window; |
| } |
| |
| namespace base { |
| class TimeDelta; |
| } |
| |
| namespace gfx { |
| struct FontRenderParams; |
| class Image; |
| class Size; |
| } // namespace gfx |
| |
| namespace printing { |
| class PrintingContextLinux; |
| class PrintDialogLinuxInterface; |
| } // namespace printing |
| |
| namespace ui { |
| |
| class CursorThemeManagerObserver; |
| class DeviceScaleFactorObserver; |
| class Event; |
| class LinuxInputMethodContext; |
| class LinuxInputMethodContextDelegate; |
| class LinuxUiTheme; |
| class NativeTheme; |
| class NavButtonProvider; |
| class SelectFileDialog; |
| class SelectFilePolicy; |
| class WindowButtonOrderObserver; |
| class WindowFrameProvider; |
| enum class TextEditCommand; |
| |
| // Adapter class with targets to render like different toolkits. Set by any |
| // project that wants to do linux desktop native rendering. |
| class COMPONENT_EXPORT(LINUX_UI) LinuxUi { |
| public: |
| // Describes the window management actions that could be taken in response to |
| // a middle click in the non client area. |
| enum class WindowFrameAction { |
| kNone, |
| kLower, |
| kMinimize, |
| kToggleMaximize, |
| kMenu, |
| }; |
| |
| // The types of clicks that might invoke a WindowFrameAction. |
| enum class WindowFrameActionSource { |
| kDoubleClick, |
| kMiddleClick, |
| kRightClick, |
| }; |
| |
| struct FontSettings { |
| std::string family; |
| int size_pixels = 0; |
| // Holds a bitfield of gfx::Font::Style values. |
| int style = 0; |
| // A standard font weight as used in Pango. Must be a value in [1, 999]. |
| int weight = 0; |
| }; |
| |
| LinuxUi(const LinuxUi&) = delete; |
| LinuxUi& operator=(const LinuxUi&) = delete; |
| virtual ~LinuxUi(); |
| |
| // Sets the dynamically loaded singleton that draws the desktop native UI. |
| // Returns the old instance if any. |
| static LinuxUi* SetInstance(LinuxUi* instance); |
| |
| // Returns a LinuxUI instance for the toolkit used in the user's desktop |
| // environment. |
| // |
| // Can return NULL, in case no toolkit has been set. (For example, if we're |
| // running with the "--ash" flag.) |
| static LinuxUi* instance(); |
| |
| // Registers |observer| to be notified about changes to the device |
| // scale factor. |
| void AddDeviceScaleFactorObserver(DeviceScaleFactorObserver* observer); |
| |
| // Unregisters |observer| from receiving changes to the device scale |
| // factor. |
| void RemoveDeviceScaleFactorObserver(DeviceScaleFactorObserver* observer); |
| |
| // Adds |observer| and makes initial OnCursorThemNameChanged() and/or |
| // OnCursorThemeSizeChanged() calls if the respective settings were set. |
| void AddCursorThemeObserver(CursorThemeManagerObserver* observer); |
| |
| void RemoveCursorThemeObserver(CursorThemeManagerObserver* observer); |
| |
| // Returns details about the default UI font. |
| FontSettings GetDefaultFontDescription(); |
| |
| // Determines the device scale factor for all screens. |
| const display::DisplayConfig& display_config() const { |
| return display_config_; |
| } |
| |
| // Returns true on success. If false is returned, this instance shouldn't |
| // be used and the behavior of all functions is undefined. |
| [[nodiscard]] virtual bool Initialize() = 0; |
| |
| // Caches the default font render parameters. This doesn't need to be called |
| // explicitly since the first call to get the font settings will implicitly |
| // initialize the default front render parameters. |
| virtual void InitializeFontSettings() = 0; |
| |
| virtual base::TimeDelta GetCursorBlinkInterval() const = 0; |
| |
| // Returns the icon for a given content type from the icon theme. |
| // TODO(davidben): Add an observer for the theme changing, so we can drop the |
| // caches. |
| virtual gfx::Image GetIconForContentType(const std::string& content_type, |
| int size, |
| float scale) const = 0; |
| |
| // Returns a map of KeyboardEvent code to KeyboardEvent key values. |
| virtual base::flat_map<std::string, std::string> GetKeyboardLayoutMap() = 0; |
| |
| #if BUILDFLAG(ENABLE_PRINTING) |
| virtual printing::PrintDialogLinuxInterface* CreatePrintDialog( |
| printing::PrintingContextLinux* context) = 0; |
| |
| virtual gfx::Size GetPdfPaperSize( |
| printing::PrintingContextLinux* context) = 0; |
| #endif |
| |
| // Returns a native file selection dialog. `listener` is of type |
| // SelectFileDialog::Listener. TODO(thomasanderson): Move |
| // SelectFileDialog::Listener to SelectFileDialogListener so that it can be |
| // forward declared. |
| virtual SelectFileDialog* CreateSelectFileDialog( |
| void* listener, |
| std::unique_ptr<SelectFilePolicy> policy) const = 0; |
| |
| // Returns the prefererd theme name for cursor loading. |
| virtual std::string GetCursorThemeName() = 0; |
| |
| // Returns the preferred size for cursor bitmaps. A value of 64 indicates |
| // that 64x64 px bitmaps are preferred. |
| virtual int GetCursorThemeSize() = 0; |
| |
| // Returns a platform specific input method context. |
| virtual std::unique_ptr<LinuxInputMethodContext> CreateInputMethodContext( |
| LinuxInputMethodContextDelegate* delegate) const = 0; |
| |
| // Matches a key event against the users' platform specific key bindings. |
| // Returns ui::TextEditCommand::INVALID_COMMAND if the key event doesn't |
| // correspond to a predefined key binding. |
| // |
| // `text_flags` is the current ui::TextInputFlags if available. |
| virtual TextEditCommand GetTextEditCommandForEvent(const Event& event, |
| int text_flags) = 0; |
| |
| // Returns the default font rendering settings. |
| virtual gfx::FontRenderParams GetDefaultFontRenderParams() = 0; |
| |
| // Indicates if animations are enabled by the toolkit. |
| virtual bool AnimationsEnabled() const = 0; |
| |
| // Notifies the observer about changes about how window buttons should be |
| // laid out. |
| virtual void AddWindowButtonOrderObserver( |
| WindowButtonOrderObserver* observer) = 0; |
| |
| // Removes the observer from the LinuxUI's list. |
| virtual void RemoveWindowButtonOrderObserver( |
| WindowButtonOrderObserver* observer) = 0; |
| |
| // What action we should take when the user clicks on the non-client area. |
| // |source| describes the type of click. |
| virtual WindowFrameAction GetWindowFrameAction( |
| WindowFrameActionSource source) = 0; |
| |
| // Returns the command line flags that should be copied to subprocesses |
| // to have the same toolkit and version as this process. |
| virtual std::vector<std::string> GetCmdLineFlagsForCopy() const = 0; |
| |
| protected: |
| struct CmdLineArgs { |
| CmdLineArgs(); |
| CmdLineArgs(CmdLineArgs&&); |
| CmdLineArgs& operator=(CmdLineArgs&&); |
| ~CmdLineArgs(); |
| |
| // `argc` is modified by toolkits, so store it explicitly. |
| int argc = 0; |
| |
| // Contains C-strings that point into `args`. `argv.size()` >= `argc`. |
| std::vector<char*> argv; |
| |
| // `argv` concatenated with NUL characters. |
| std::vector<char> args; |
| }; |
| |
| LinuxUi(); |
| |
| static CmdLineArgs CopyCmdLine(const base::CommandLine& command_line); |
| |
| base::ObserverList<DeviceScaleFactorObserver>::Unchecked& |
| device_scale_factor_observer_list() { |
| return device_scale_factor_observer_list_; |
| } |
| |
| base::ObserverList<CursorThemeManagerObserver>& cursor_theme_observers() { |
| return cursor_theme_observer_list_; |
| } |
| |
| display::DisplayConfig& display_config() { return display_config_; } |
| |
| void set_default_font_settings( |
| const std::optional<FontSettings>& default_font_settings) { |
| default_font_settings_ = default_font_settings; |
| } |
| |
| private: |
| // Objects to notify when the device scale factor changes. |
| base::ObserverList<DeviceScaleFactorObserver>::Unchecked |
| device_scale_factor_observer_list_; |
| |
| // Objects to notify when the cursor theme or size changes. |
| base::ObserverList<CursorThemeManagerObserver> cursor_theme_observer_list_; |
| |
| display::DisplayConfig display_config_; |
| |
| std::optional<FontSettings> default_font_settings_; |
| }; |
| |
| class COMPONENT_EXPORT(LINUX_UI) LinuxUiTheme { |
| public: |
| LinuxUiTheme(const LinuxUiTheme&) = delete; |
| LinuxUiTheme& operator=(const LinuxUiTheme&) = delete; |
| virtual ~LinuxUiTheme(); |
| |
| // Returns the LinuxUi instance for the given window, or the default instance |
| // if the window is nullptr. |
| static LinuxUiTheme* GetForWindow(aura::Window* window); |
| |
| // Returns the LinuxUi instance for the given profile, or the default instance |
| // if the profile is nullptr. |
| static LinuxUiTheme* GetForProfile(Profile* profile); |
| |
| // Returns the native theme for this toolkit. |
| virtual ui::NativeTheme* GetNativeTheme() const = 0; |
| |
| virtual bool GetColor(int id, |
| SkColor* color, |
| bool use_custom_frame) const = 0; |
| virtual bool GetDisplayProperty(int id, int* result) const = 0; |
| |
| // Returns the preferences that we pass to Blink. |
| virtual void GetFocusRingColor(SkColor* color) const = 0; |
| virtual void GetActiveSelectionBgColor(SkColor* color) const = 0; |
| virtual void GetActiveSelectionFgColor(SkColor* color) const = 0; |
| virtual void GetInactiveSelectionBgColor(SkColor* color) const = 0; |
| virtual void GetInactiveSelectionFgColor(SkColor* color) const = 0; |
| |
| // Only used on GTK to indicate if the dark GTK theme variant is |
| // preferred. |
| virtual bool PreferDarkTheme() const = 0; |
| |
| // Override the toolkit's dark mode preference. Used when the dark mode |
| // setting is provided by org.freedesktop.appearance instead of the toolkit. |
| virtual void SetDarkTheme(bool dark) = 0; |
| |
| // Override the toolkit's accent color. |
| virtual void SetAccentColor(std::optional<SkColor> accent_color) = 0; |
| |
| // Returns a new NavButtonProvider, or nullptr if the underlying |
| // toolkit does not support drawing client-side navigation buttons. |
| virtual std::unique_ptr<NavButtonProvider> CreateNavButtonProvider() = 0; |
| |
| // Returns a WindowFrameProvider, or nullptr if the underlying toolkit does |
| // not support drawing client-side window decorations. |solid_frame| indicates |
| // if transparency is unsupported and the frame should be rendered opaque. |
| // The returned object is not owned by the caller and will remain alive until |
| // the process ends. |
| virtual WindowFrameProvider* GetWindowFrameProvider(bool solid_frame, |
| bool tiled, |
| bool maximized) = 0; |
| |
| protected: |
| LinuxUiTheme(); |
| }; |
| |
| // This is used internally by LinuxUi implementations and linux_ui_factory to |
| // allow converting a LinuxUi to a LinuxUiTheme. Users should not use (and have |
| // no way of obtaining) an instance of this class. |
| class LinuxUiAndTheme : public LinuxUi, public LinuxUiTheme { |
| public: |
| ~LinuxUiAndTheme() override = default; |
| }; |
| |
| } // namespace ui |
| |
| namespace base { |
| |
| template <> |
| struct ScopedObservationTraits<ui::LinuxUi, ui::CursorThemeManagerObserver> { |
| static void AddObserver(ui::LinuxUi* source, |
| ui::CursorThemeManagerObserver* observer) { |
| source->AddCursorThemeObserver(observer); |
| } |
| static void RemoveObserver(ui::LinuxUi* source, |
| ui::CursorThemeManagerObserver* observer) { |
| source->RemoveCursorThemeObserver(observer); |
| } |
| }; |
| |
| template <> |
| struct ScopedObservationTraits<ui::LinuxUi, ui::DeviceScaleFactorObserver> { |
| static void AddObserver(ui::LinuxUi* source, |
| ui::DeviceScaleFactorObserver* observer) { |
| source->AddDeviceScaleFactorObserver(observer); |
| } |
| static void RemoveObserver(ui::LinuxUi* source, |
| ui::DeviceScaleFactorObserver* observer) { |
| source->RemoveDeviceScaleFactorObserver(observer); |
| } |
| }; |
| |
| template <> |
| struct ScopedObservationTraits<ui::LinuxUi, ui::WindowButtonOrderObserver> { |
| static void AddObserver(ui::LinuxUi* source, |
| ui::WindowButtonOrderObserver* observer) { |
| source->AddWindowButtonOrderObserver(observer); |
| } |
| static void RemoveObserver(ui::LinuxUi* source, |
| ui::WindowButtonOrderObserver* observer) { |
| source->RemoveWindowButtonOrderObserver(observer); |
| } |
| }; |
| |
| } // namespace base |
| |
| #endif // UI_LINUX_LINUX_UI_H_ |