diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-09-03 13:32:17 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-10-01 14:31:55 +0200 |
commit | 21ba0c5d4bf8fba15dddd97cd693bad2358b77fd (patch) | |
tree | 91be119f694044dfc1ff9fdc054459e925de9df0 /chromium/ui/gtk | |
parent | 03c549e0392f92c02536d3f86d5e1d8dfa3435ac (diff) | |
download | qtwebengine-chromium-21ba0c5d4bf8fba15dddd97cd693bad2358b77fd.tar.gz |
BASELINE: Update Chromium to 92.0.4515.166
Change-Id: I42a050486714e9e54fc271f2a8939223a02ae364
Diffstat (limited to 'chromium/ui/gtk')
39 files changed, 917 insertions, 682 deletions
diff --git a/chromium/ui/gtk/BUILD.gn b/chromium/ui/gtk/BUILD.gn index 47ec07c887d..7bdb5a0e439 100644 --- a/chromium/ui/gtk/BUILD.gn +++ b/chromium/ui/gtk/BUILD.gn @@ -2,10 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//build/buildflag_header.gni") import("//build/config/chromeos/ui_mode.gni") import("//build/config/features.gni") -import("//build/config/linux/gtk/gtk.gni") import("//build/config/ozone.gni") import("//build/config/ui.gni") import("//printing/buildflags/buildflags.gni") @@ -15,18 +13,13 @@ import("//tools/generate_stubs/rules.gni") assert(is_linux || is_chromeos_lacros || is_chromeos, "This file should only be referenced on Linux") -buildflag_header("gtk_buildflags") { - header = "gtk_buildflags.h" - - flags = [ "GTK_VERSION=$gtk_version" ] -} - source_set("gtk_types") { - sources = [ "gtk_types.h" ] - deps = [ ":gtk_buildflags" ] + visibility = [ ":gtk_stubs" ] + public = [ "gtk_types.h" ] } generate_stubs("gtk_stubs") { + visibility = [ ":gtk" ] sigs = [ "gdk_pixbuf.sigs", "gdk.sigs", @@ -36,29 +29,17 @@ generate_stubs("gtk_stubs") { ] extra_header = "gtk.fragment" output_name = "gtk_stubs" - deps = [ + public_deps = [ ":gtk_types", "//build/config/linux/gtk", + "//build/config/linux/gtk:gtkprint", ] logging_function = "LogNoop()" logging_include = "ui/gtk/log_noop.h" } -component("gtk_ui_delegate") { - public = [ "gtk_ui_delegate.h" ] - sources = [ "gtk_ui_delegate.cc" ] - deps = [ - "//base", - "//ui/gfx", - ] - public_deps = [ ":gtk_buildflags" ] - defines = [ "IS_GTK_IMPL" ] -} - component("gtk") { - public = [ "gtk_ui.h" ] - - friend = [ ":gtk_unittests" ] + public = [ "gtk_ui_factory.h" ] sources = [ "gtk_color_mixers.cc", @@ -68,6 +49,9 @@ component("gtk") { "gtk_key_bindings_handler.cc", "gtk_key_bindings_handler.h", "gtk_ui.cc", + "gtk_ui.h", + "gtk_ui_factory.cc", + "gtk_ui_platform.h", "gtk_util.cc", "gtk_util.h", "input_method_context_impl_gtk.cc", @@ -105,16 +89,12 @@ component("gtk") { deps = [ ":gtk_stubs", - ":gtk_types", "//base", - "//build/config/linux/gtk:gtkprint", - "//printing", "//skia", # GTK pulls pangoft2, which requires HarfBuzz symbols. When linking # our own HarfBuzz avoid mixing symbols from system HarfBuzz and # our own through the indirect dependency to harfbuzz-ng here. - "//build/config/linux/gtk", "//third_party:freetype_harfbuzz", "//ui/aura", "//ui/base", @@ -137,11 +117,34 @@ component("gtk") { "//ui/views", ] + if (enable_basic_printing) { + deps += [ "//printing" ] + } + if (use_cups) { deps += [ "//printing/mojom" ] } - public_deps = [ ":gtk_ui_delegate" ] + if (use_x11 || ozone_platform_x11) { + sources += [ + "x/gtk_event_loop_x11.cc", + "x/gtk_event_loop_x11.h", + "x/gtk_ui_platform_x11.cc", + "x/gtk_ui_platform_x11.h", + ] + deps += [ + "//ui/events/platform/x11", + "//ui/gfx/x", + "//ui/platform_window/x11", + ] + } + + if (ozone_platform_wayland) { + sources += [ + "wayland/gtk_ui_platform_wayland.cc", + "wayland/gtk_ui_platform_wayland.h", + ] + } # TODO: This should be removed. if (use_ozone) { @@ -156,12 +159,10 @@ test("gtk_unittests") { ":gtk", "//base/test:run_all_unittests", "//base/test:test_support", - - # Required so that including gtk_util.h can resolve <gtk/gtk.h>. - "//build/config/linux/gtk", "//testing/gtest", "//ui/base:features", "//ui/native_theme", "//ui/native_theme:test_support", + "//ui/views", ] } diff --git a/chromium/ui/gtk/gdk.sigs b/chromium/ui/gtk/gdk.sigs index a2170ffd40d..7a393ed7080 100644 --- a/chromium/ui/gtk/gdk.sigs +++ b/chromium/ui/gtk/gdk.sigs @@ -17,4 +17,20 @@ GdkTexture* gdk_memory_texture_new(int width, int height, GdkMemoryFormat format int gdk_paintable_get_intrinsic_width(GdkPaintable* paintable); int gdk_paintable_get_intrinsic_height(GdkPaintable* paintable); GdkScreen* gdk_screen_get_default(void); +void gdk_color_free(GdkColor* color); +gboolean gdk_wayland_window_set_transient_for_exported(GdkWindow* window, char* parent_handle_str); +gboolean gdk_wayland_toplevel_set_transient_for_exported(GdkToplevel* toplevel, const char* parent_handle_str); +unsigned long gdk_x11_surface_get_xid(GdkSurface* surface); +unsigned long gdk_x11_window_get_xid(GdkWindow* window); +void gdk_event_handler_set(GdkEventFunc func, gpointer data, GDestroyNotify notify); +GdkWindow* gdk_x11_window_foreign_new_for_display(GdkDisplay* display, unsigned long window); +GdkWindow* gdk_x11_window_lookup_for_display(GdkDisplay* display, unsigned long window); +guint gdk_key_event_get_keycode(GdkEvent* event); +guint gdk_key_event_get_keyval(GdkEvent* event); +GdkSurface* gdk_event_get_surface(GdkEvent* event); +GdkModifierType gdk_event_get_modifier_state(GdkEvent *event); +GType gdk_toplevel_get_type(void); +void gdk_set_allowed_backends(const gchar* backends); +void gdk_display_notify_startup_complete(GdkDisplay* display, const char* startup_id); +guint32 gdk_keyval_to_unicode(guint keyval); gdouble gdk_screen_get_resolution(GdkScreen *screen); diff --git a/chromium/ui/gtk/gtk.sigs b/chromium/ui/gtk/gtk.sigs index 39dd8f1e29d..5bf454bbc67 100644 --- a/chromium/ui/gtk/gtk.sigs +++ b/chromium/ui/gtk/gtk.sigs @@ -52,3 +52,135 @@ void gtk_style_context_add_provider_for_screen(GdkScreen* screen, GtkStyleProvid void gtk_style_context_add_provider_for_display(GdkDisplay* display, GtkStyleProvider* provider, guint priority); void gtk_style_context_remove_provider_for_screen(GdkScreen* screen, GtkStyleProvider* provider); void gtk_style_context_remove_provider_for_display(GdkDisplay* display, GtkStyleProvider* provider); +void gtk_window_destroy(GtkWindow* window); +GtkIconTheme* gtk_icon_theme_get_for_display(GdkDisplay* display); +GtkIconTheme* gtk_icon_theme_get_default(void); +gboolean gtk_widget_path_iter_has_class(const GtkWidgetPath* path, gint pos, const gchar* name); +GdkWindow* gtk_widget_get_window(GtkWidget* widget); +void gtk_main_do_event(GdkEvent *event); +guint gtk_get_major_version(void); +guint gtk_get_minor_version(void); +guint gtk_get_micro_version(void); +void gtk_window_present(GtkWindow* window); +void gtk_window_present_with_time(GtkWindow* window, guint32 timestamp); +GType gtk_box_get_type(void); +GType gtk_button_get_type(void); +GType gtk_cell_view_get_type(void); +GType gtk_combo_box_text_get_type(void); +GType gtk_entry_get_type(void); +GType gtk_file_chooser_get_type(void); +GType gtk_frame_get_type(void); +GType gtk_header_bar_get_type(void); +GType gtk_image_get_type(void); +GType gtk_info_bar_get_type(void); +GType gtk_label_get_type(void); +GType gtk_print_unix_dialog_get_type(void); +GType gtk_range_get_type(void); +GType gtk_scale_get_type(void); +GType gtk_scrollbar_get_type(void); +GType gtk_scrolled_window_get_type(void); +GType gtk_separator_get_type(void); +GType gtk_spinner_get_type(void); +GType gtk_style_provider_get_type(void); +GType gtk_text_view_get_type(void); +GType gtk_toggle_button_get_type(void); +GType gtk_tree_model_get_type(void); +GType gtk_tree_view_get_type(void); +GType gtk_widget_get_type(void); +GType gtk_window_get_type(void); +GtkWidget* gtk_combo_box_new_with_model(GtkTreeModel* model); +GtkCssProvider* gtk_css_provider_new(void); +void gtk_disable_setlocale(void); +void gtk_enumerate_printers(GtkPrinterFunc func, gpointer data, GDestroyNotify destroy, gboolean wait); +void gtk_file_chooser_add_filter(GtkFileChooser* chooser, GtkFileFilter* filter); +GFile* gtk_file_chooser_get_file(GtkFileChooser* chooser); +GtkFileFilter* gtk_file_chooser_get_filter(GtkFileChooser* chooser); +void gtk_file_chooser_set_create_folders(GtkFileChooser* chooser, gboolean create_folders); +void gtk_file_chooser_set_current_name(GtkFileChooser* chooser, const gchar* name); +gboolean gtk_file_chooser_set_file(GtkFileChooser* chooser, GFile* file, GError** error); +void gtk_file_chooser_set_filter(GtkFileChooser* chooser, GtkFileFilter* filter); +void gtk_file_chooser_set_select_multiple(GtkFileChooser* chooser, gboolean select_multiple); +void gtk_file_filter_add_mime_type(GtkFileFilter* filter, const gchar* mime_type); +void gtk_file_filter_add_pattern(GtkFileFilter* filter, const gchar* pattern); +GtkFileFilter* gtk_file_filter_new(void); +void gtk_file_filter_set_name(GtkFileFilter* filter, const gchar* name); +GtkWidget* gtk_image_new(void); +void gtk_image_set_from_pixbuf(GtkImage* image, GdkPixbuf* pixbuf); +void gtk_im_context_focus_in(GtkIMContext* context); +void gtk_im_context_focus_out(GtkIMContext* context); +void gtk_im_context_get_preedit_string(GtkIMContext* context, gchar** str, PangoAttrList** attrs, gint* cursor_pos); +void gtk_im_context_reset(GtkIMContext* context); +void gtk_im_context_set_cursor_location(GtkIMContext* context, const GdkRectangle* area); +GtkIMContext* gtk_im_context_simple_new(void); +GtkIMContext* gtk_im_multicontext_new(void); +GtkWidget* gtk_label_new(const gchar* str); +gdouble gtk_page_setup_get_left_margin(GtkPageSetup* setup, GtkUnit unit); +gdouble gtk_page_setup_get_page_height(GtkPageSetup* setup, GtkUnit unit); +gdouble gtk_page_setup_get_page_width(GtkPageSetup* setup, GtkUnit unit); +gdouble gtk_page_setup_get_paper_height(GtkPageSetup* setup, GtkUnit unit); +GtkPaperSize* gtk_page_setup_get_paper_size(GtkPageSetup* setup); +gdouble gtk_page_setup_get_paper_width(GtkPageSetup* setup, GtkUnit unit); +gdouble gtk_page_setup_get_top_margin(GtkPageSetup* setup, GtkUnit unit); +GtkPageSetup* gtk_page_setup_new(void); +void gtk_page_setup_set_paper_size(GtkPageSetup* setup, GtkPaperSize* size); +void gtk_paper_size_free(GtkPaperSize* size); +gdouble gtk_paper_size_get_height(GtkPaperSize* size, GtkUnit unit); +GList* gtk_paper_size_get_paper_sizes(gboolean include_custom); +const gchar* gtk_paper_size_get_ppd_name(GtkPaperSize* size); +gdouble gtk_paper_size_get_width(GtkPaperSize* size, GtkUnit unit); +GtkPaperSize* gtk_paper_size_new_custom(const gchar* name, const gchar* display_name, gdouble width, gdouble height, GtkUnit unit); +GtkPageSetup* gtk_printer_get_default_page_size(GtkPrinter* printer); +const gchar* gtk_printer_get_name(GtkPrinter* printer); +gboolean gtk_printer_is_default(GtkPrinter* printer); +GtkPrintJob* gtk_print_job_new(const gchar* title, GtkPrinter* printer, GtkPrintSettings* settings, GtkPageSetup* page_setup); +void gtk_print_job_send(GtkPrintJob* job, GtkPrintJobCompleteFunc callback, gpointer user_data, GDestroyNotify dnotify); +gboolean gtk_print_job_set_source_file(GtkPrintJob* job, const gchar* filename, GError** error); +GtkPrintSettings* gtk_print_settings_copy(GtkPrintSettings* other); +GtkPageOrientation gtk_print_settings_get_orientation(GtkPrintSettings* settings); +GtkPageRange* gtk_print_settings_get_page_ranges(GtkPrintSettings* settings, gint *num_ranges); +const gchar* gtk_print_settings_get_printer(GtkPrintSettings* settings); +GtkPrintPages gtk_print_settings_get_print_pages(GtkPrintSettings* settings); +gint gtk_print_settings_get_resolution(GtkPrintSettings* settings); +GtkPrintSettings* gtk_print_settings_new(void); +void gtk_print_settings_set(GtkPrintSettings* settings, const gchar* key, const gchar* value); +void gtk_print_settings_set_collate(GtkPrintSettings* settings, gboolean collate); +void gtk_print_settings_set_n_copies(GtkPrintSettings* settings, gint num_copies); +void gtk_print_settings_set_orientation(GtkPrintSettings* settings, GtkPageOrientation orientation); +void gtk_print_settings_set_printer_lpi(GtkPrintSettings* settings, gdouble lpi); +void gtk_print_settings_set_print_pages(GtkPrintSettings* settings, GtkPrintPages pages); +void gtk_print_settings_set_resolution_xy(GtkPrintSettings* settings, gint resolution_x, gint resolution_y); +GtkPageSetup* gtk_print_unix_dialog_get_page_setup(GtkPrintUnixDialog* dialog); +GtkPrinter* gtk_print_unix_dialog_get_selected_printer(GtkPrintUnixDialog* dialog); +GtkPrintSettings* gtk_print_unix_dialog_get_settings(GtkPrintUnixDialog* dialog); +GtkWidget* gtk_print_unix_dialog_new(const char* title, GtkWindow* parent); +void gtk_print_unix_dialog_set_embed_page_setup(GtkPrintUnixDialog* dialog, gboolean embed); +void gtk_print_unix_dialog_set_has_selection(GtkPrintUnixDialog* dialog, gboolean has_selection); +void gtk_print_unix_dialog_set_manual_capabilities(GtkPrintUnixDialog* dialog, GtkPrintCapabilities capabilities); +void gtk_print_unix_dialog_set_settings(GtkPrintUnixDialog* dialog, GtkPrintSettings* settings); +void gtk_print_unix_dialog_set_support_selection(GtkPrintUnixDialog* dialog, gboolean support_selection); +void gtk_render_background(GtkStyleContext* context, cairo_t* cr, gdouble x, gdouble y, gdouble width, gdouble height); +void gtk_render_focus(GtkStyleContext* context, cairo_t* cr, gdouble x, gdouble y, gdouble width, gdouble height); +void gtk_render_frame(GtkStyleContext* context, cairo_t* cr, gdouble x, gdouble y, gdouble width, gdouble height); +GtkWidget* gtk_separator_new(GtkOrientation orientation); +void gtk_style_context_add_class(GtkStyleContext* context, const gchar* class_name); +void gtk_style_context_add_provider(GtkStyleContext* context, GtkStyleProvider* provider, guint priority); +GtkStateFlags gtk_style_context_get_state(GtkStyleContext* context); +gboolean gtk_style_context_has_class(GtkStyleContext* context, const gchar* class_name); +void gtk_style_context_set_scale(GtkStyleContext* context, gint scale); +void gtk_style_context_set_state(GtkStyleContext* context, GtkStateFlags flags); +PangoContext* gtk_widget_get_pango_context(GtkWidget* widget); +GtkWidget* gtk_widget_get_parent(GtkWidget* widget); +void gtk_widget_get_preferred_size(GtkWidget* widget, GtkRequisition* minimum_size, GtkRequisition* natural_size); +gint gtk_widget_get_scale_factor(GtkWidget* widget); +GtkStyleContext* gtk_widget_get_style_context(GtkWidget* widget); +void gtk_widget_hide(GtkWidget* widget); +void gtk_widget_realize(GtkWidget* widget); +void gtk_widget_set_can_focus(GtkWidget* widget, gboolean can_focus); +void gtk_widget_set_name(GtkWidget* widget, const gchar* name); +void gtk_widget_set_parent(GtkWidget* widget, GtkWidget* parent); +void gtk_widget_set_sensitive(GtkWidget* widget, gboolean sensitive); +void gtk_widget_set_size_request(GtkWidget* widget, gint width, gint height); +void gtk_widget_set_state_flags(GtkWidget* widget, GtkStateFlags flags, gboolean clear); +void gtk_widget_show(GtkWidget* widget); +void gtk_window_set_modal(GtkWindow* window, gboolean modal); +void gtk_print_settings_set_printer(GtkPrintSettings* settings, const gchar* printer); diff --git a/chromium/ui/gtk/gtk_color_mixers.cc b/chromium/ui/gtk/gtk_color_mixers.cc index 044ddd4390c..b4b0710438a 100644 --- a/chromium/ui/gtk/gtk_color_mixers.cc +++ b/chromium/ui/gtk/gtk_color_mixers.cc @@ -21,13 +21,19 @@ namespace gtk { void AddGtkNativeCoreColorMixer( ui::ColorProvider* provider, ui::ColorProviderManager::ColorMode color_mode, - ui::ColorProviderManager::ContrastMode contrast_mode) { + ui::ColorProviderManager::ContrastMode contrast_mode, + ui::ColorProviderManager::ThemeName theme_name) { + // `theme_name` is empty when using the system theme. We do not initialize the + // GTK mixer in this case. + if (theme_name.empty()) + return; + ui::ColorMixer& mixer = provider->AddMixer(); ui::ColorSet::ColorMap color_map; for (ui::ColorId id = ui::kUiColorsStart; id < ui::kUiColorsEnd; ++id) { // Add GTK color definitions to the map if they exist. - base::Optional<SkColor> color = gtk::SkColorFromColorId(id); + absl::optional<SkColor> color = gtk::SkColorFromColorId(id); if (color) color_map[id] = *color; } diff --git a/chromium/ui/gtk/gtk_color_mixers.h b/chromium/ui/gtk/gtk_color_mixers.h index 3b4edb55e00..eb7b92bcfe6 100644 --- a/chromium/ui/gtk/gtk_color_mixers.h +++ b/chromium/ui/gtk/gtk_color_mixers.h @@ -16,7 +16,8 @@ namespace gtk { void AddGtkNativeCoreColorMixer( ui::ColorProvider* provider, ui::ColorProviderManager::ColorMode color_mode, - ui::ColorProviderManager::ContrastMode contrast_mode); + ui::ColorProviderManager::ContrastMode contrast_mode, + ui::ColorProviderManager::ThemeName theme_name); } // namespace gtk diff --git a/chromium/ui/gtk/gtk_compat.cc b/chromium/ui/gtk/gtk_compat.cc index 0610d8aa5dd..d05e866401f 100644 --- a/chromium/ui/gtk/gtk_compat.cc +++ b/chromium/ui/gtk/gtk_compat.cc @@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "base/debug/leak_annotations.h" #include "base/no_destructor.h" +#include "ui/gfx/color_palette.h" #include "ui/gtk/gtk_stubs.h" namespace gtk { @@ -19,9 +20,29 @@ namespace gtk { namespace { -void* DlOpen(const char* library_name) { +struct Gdk3Rgba { + gdouble r; + gdouble g; + gdouble b; + gdouble a; +}; + +struct Gdk4Rgba { + float r; + float g; + float b; + float a; +}; + +template <typename T> +SkColor GdkRgbaToSkColor(const T& color) { + return SkColorSetARGB(color.a * 255, color.r * 255, color.g * 255, + color.b * 255); +} + +void* DlOpen(const char* library_name, bool check = true) { void* library = dlopen(library_name, RTLD_LAZY | RTLD_GLOBAL); - CHECK(library); + CHECK(!check || library); return library; } @@ -51,8 +72,8 @@ void* GetLibGdk3() { return libgdk3; } -void* GetLibGtk3() { - static void* libgtk3 = DlOpen("libgtk-3.so.0"); +void* GetLibGtk3(bool check = true) { + static void* libgtk3 = DlOpen("libgtk-3.so.0", check); return libgtk3; } @@ -67,14 +88,9 @@ void* GetLibGtk() { return GetLibGtk3(); } -gfx::Insets InsetsFromGtkBorder(const GtkBorder& border) { - return gfx::Insets(border.top, border.left, border.bottom, border.right); -} - -} // namespace - -bool LoadGtk(int gtk_version) { - if (gtk_version < 4) { +bool LoadGtkImpl(int gtk_version) { + // Prefer GTK3 for now as the GTK4 ecosystem is still immature. + if (GetLibGtk3(false)) { ui_gtk::InitializeGdk_pixbuf(GetLibGdkPixbuf()); ui_gtk::InitializeGdk(GetLibGdk3()); ui_gtk::InitializeGtk(GetLibGtk3()); @@ -92,6 +108,17 @@ bool LoadGtk(int gtk_version) { return true; } +gfx::Insets InsetsFromGtkBorder(const GtkBorder& border) { + return gfx::Insets(border.top, border.left, border.bottom, border.right); +} + +} // namespace + +bool LoadGtk() { + static bool loaded = LoadGtkImpl(GTK_MAJOR_VERSION); + return loaded; +} + const base::Version& GtkVersion() { static base::NoDestructor<base::Version> gtk_version( std::vector<uint32_t>{gtk_get_major_version(), gtk_get_minor_version(), @@ -172,6 +199,45 @@ gfx::Insets GtkStyleContextGetMargin(GtkStyleContext* context) { } DISABLE_CFI_ICALL +SkColor GtkStyleContextGetColor(GtkStyleContext* context) { + static void* get_color = DlSym(GetLibGtk(), "gtk_style_context_get_color"); + if (GtkCheckVersion(4)) { + Gdk4Rgba color; + DlCast<void(GtkStyleContext*, Gdk4Rgba*)>(get_color)(context, &color); + return GdkRgbaToSkColor(color); + } + Gdk3Rgba color; + DlCast<void(GtkStyleContext*, GtkStateFlags, Gdk3Rgba*)>(get_color)( + context, gtk_style_context_get_state(context), &color); + return GdkRgbaToSkColor(color); +} + +DISABLE_CFI_ICALL +SkColor GtkStyleContextGetBackgroundColor(GtkStyleContext* context) { + DCHECK(!GtkCheckVersion(4)); + static void* get_bg_color = + DlSym(GetLibGtk(), "gtk_style_context_get_background_color"); + Gdk3Rgba color; + DlCast<void(GtkStyleContext*, GtkStateFlags, Gdk3Rgba*)>(get_bg_color)( + context, gtk_style_context_get_state(context), &color); + return GdkRgbaToSkColor(color); +} + +DISABLE_CFI_ICALL +SkColor GtkStyleContextLookupColor(GtkStyleContext* context, + const gchar* color_name) { + DCHECK(!GtkCheckVersion(4)); + static void* lookup_color = + DlSym(GetLibGtk(), "gtk_style_context_lookup_color"); + Gdk3Rgba color; + if (DlCast<gboolean(GtkStyleContext*, const gchar*, Gdk3Rgba*)>(lookup_color)( + context, color_name, &color)) { + return GdkRgbaToSkColor(color); + } + return gfx::kPlaceholderColor; +} + +DISABLE_CFI_ICALL bool GtkImContextFilterKeypress(GtkIMContext* context, GdkEventKey* event) { static void* filter = DlSym(GetLibGtk(), "gtk_im_context_filter_keypress"); if (GtkCheckVersion(4)) { @@ -213,6 +279,28 @@ void GtkRenderIcon(GtkStyleContext* context, } } +DISABLE_CFI_ICALL +GtkWidget* GtkToplevelWindowNew() { + static void* window_new = DlSym(GetLibGtk(), "gtk_window_new"); + if (GtkCheckVersion(4)) + return DlCast<GtkWidget*()>(window_new)(); + return DlCast<GtkWidget*(GtkWindowType)>(window_new)(GTK_WINDOW_TOPLEVEL); +} + +DISABLE_CFI_ICALL +void GtkCssProviderLoadFromData(GtkCssProvider* css_provider, + const char* data, + gssize length) { + static void* load = DlSym(GetLibGtk(), "gtk_css_provider_load_from_data"); + if (GtkCheckVersion(4)) { + DlCast<void(GtkCssProvider*, const char*, gssize)>(load)(css_provider, data, + length); + } else { + DlCast<gboolean(GtkCssProvider*, const char*, gssize, GError**)>(load)( + css_provider, data, length, nullptr); + } +} + ScopedGObject<GListModel> Gtk4FileChooserGetFiles(GtkFileChooser* dialog) { DCHECK(GtkCheckVersion(4)); static void* get = DlSym(GetLibGtk(), "gtk_file_chooser_get_files"); @@ -279,4 +367,45 @@ ScopedGObject<GtkIconPaintable> Gtk4IconThemeLookupByGicon( theme, icon, size, scale, direction, flags)); } +DISABLE_CFI_ICALL +GtkWidget* GtkFileChooserDialogNew(const gchar* title, + GtkWindow* parent, + GtkFileChooserAction action, + const gchar* first_button_text, + GtkResponseType first_response, + const gchar* second_button_text, + GtkResponseType second_response) { + static void* create = DlSym(GetLibGtk(), "gtk_file_chooser_dialog_new"); + return DlCast<GtkWidget*(const gchar*, GtkWindow*, GtkFileChooserAction, + const gchar*, ...)>(create)( + title, parent, action, first_button_text, first_response, + second_button_text, second_response, nullptr); +} + +DISABLE_CFI_ICALL +GtkTreeStore* GtkTreeStoreNew(GType type) { + static void* create = DlSym(GetLibGtk(), "gtk_tree_store_new"); + return DlCast<GtkTreeStore*(gint, ...)>(create)(1, type); +} + +DISABLE_CFI_ICALL +GdkEventType GdkEventGetEventType(GdkEvent* event) { + static void* get = DlSym(GetLibGtk(), "gdk_event_get_event_type"); + return DlCast<GdkEventType(GdkEvent*)>(get)(event); +} + +DISABLE_CFI_ICALL +guint32 GdkEventGetTime(GdkEvent* event) { + static void* get = DlSym(GetLibGtk(), "gdk_event_get_time"); + return DlCast<guint32(GdkEvent*)>(get)(event); +} + +GdkEventType GdkKeyPress() { + return static_cast<GdkEventType>(GtkCheckVersion(4) ? 4 : 8); +} + +GdkEventType GdkKeyRelease() { + return static_cast<GdkEventType>(GtkCheckVersion(4) ? 5 : 9); +} + } // namespace gtk diff --git a/chromium/ui/gtk/gtk_compat.h b/chromium/ui/gtk/gtk_compat.h index 5d87d1b14c3..a1a63ded31e 100644 --- a/chromium/ui/gtk/gtk_compat.h +++ b/chromium/ui/gtk/gtk_compat.h @@ -9,11 +9,11 @@ #include <gdk/gdk.h> #include <gio/gio.h> #include <gtk/gtk.h> +#include <gtk/gtkunixprint.h> #include <string> #include <vector> -#include "base/component_export.h" #include "base/files/file_path.h" #include "base/version.h" #include "ui/base/glib/scoped_gobject.h" @@ -28,10 +28,16 @@ extern "C" { #include "ui/gtk/gtk.sigs" } +#define GDK_KEY_PRESS Do_not_use_GDK_KEY_PRESS_because_it_is_not_ABI_compatible +#define GDK_KEY_RELEASE \ + Do_not_use_GDK_KEY_RELEASE_because_it_is_not_ABI_compatible + +using SkColor = uint32_t; + namespace gtk { // Loads libgtk and related libraries and returns true on success. -COMPONENT_EXPORT(GTK) bool LoadGtk(int gtk_version); +bool LoadGtk(); const base::Version& GtkVersion(); @@ -51,6 +57,15 @@ gfx::Insets GtkStyleContextGetBorder(GtkStyleContext* context); gfx::Insets GtkStyleContextGetMargin(GtkStyleContext* context); +SkColor GtkStyleContextGetColor(GtkStyleContext* context); + +// Only available in Gtk3. +SkColor GtkStyleContextGetBackgroundColor(GtkStyleContext* context); + +// Only available in Gtk3. +SkColor GtkStyleContextLookupColor(GtkStyleContext* context, + const gchar* color_name); + bool GtkImContextFilterKeypress(GtkIMContext* context, GdkEventKey* event); bool GtkFileChooserSetCurrentFolder(GtkFileChooser* dialog, @@ -63,6 +78,12 @@ void GtkRenderIcon(GtkStyleContext* context, double x, double y); +GtkWidget* GtkToplevelWindowNew(); + +void GtkCssProviderLoadFromData(GtkCssProvider* css_provider, + const char* data, + gssize length); + ScopedGObject<GListModel> Gtk4FileChooserGetFiles(GtkFileChooser* dialog); ScopedGObject<GtkIconInfo> Gtk3IconThemeLookupByGicon(GtkIconTheme* theme, @@ -94,6 +115,32 @@ void GtkStyleContextGet(GtkStyleContext* context, ...); void GtkStyleContextGetStyle(GtkStyleContext* context, ...); +// These variadic functions do not have corresponding va_list equivalents, +// so instances with only a fixed set of arguments are provided. + +GtkWidget* GtkFileChooserDialogNew(const gchar* title, + GtkWindow* parent, + GtkFileChooserAction action, + const gchar* first_button_text, + GtkResponseType first_response, + const gchar* second_button_text, + GtkResponseType second_response); + +GtkTreeStore* GtkTreeStoreNew(GType type); + +// These functions have dropped "const" in their signatures, so cannot be +// declared in *.sigs. + +GdkEventType GdkEventGetEventType(GdkEvent* event); + +guint32 GdkEventGetTime(GdkEvent* event); + +// Some enum values have changed between versions. + +GdkEventType GdkKeyPress(); + +GdkEventType GdkKeyRelease(); + } // namespace gtk -#endif +#endif // UI_GTK_GTK_COMPAT_H_ diff --git a/chromium/ui/gtk/gtk_key_bindings_handler.cc b/chromium/ui/gtk/gtk_key_bindings_handler.cc index bacf6abb9f2..70edaed2b04 100644 --- a/chromium/ui/gtk/gtk_key_bindings_handler.cc +++ b/chromium/ui/gtk/gtk_key_bindings_handler.cc @@ -4,9 +4,7 @@ #include "ui/gtk/gtk_key_bindings_handler.h" -#include <gdk/gdkkeysyms.h> -#include <stddef.h> - +#include <cstddef> #include <string> #include "base/logging.h" @@ -52,7 +50,7 @@ bool GtkKeyBindingsHandler::MatchEvent( // will be emitted. auto* key = reinterpret_cast<GdkEventKey*>(gdk_event); - DCHECK(key->type == GDK_KEY_PRESS || key->type == GDK_KEY_RELEASE); + DCHECK(key->type == GdkKeyPress() || key->type == GdkKeyRelease()); gtk_bindings_activate_event(G_OBJECT(handler_), key); gdk_event_free(gdk_event); @@ -90,18 +88,16 @@ void GtkKeyBindingsHandler::HandlerInit(Handler* self) { } void GtkKeyBindingsHandler::HandlerClassInit(HandlerClass* klass) { - GtkTextViewClass* text_view_class = GTK_TEXT_VIEW_CLASS(klass); - // Overrides all virtual methods related to editor key bindings. - text_view_class->backspace = BackSpace; - text_view_class->copy_clipboard = CopyClipboard; - text_view_class->cut_clipboard = CutClipboard; - text_view_class->delete_from_cursor = DeleteFromCursor; - text_view_class->insert_at_cursor = InsertAtCursor; - text_view_class->move_cursor = MoveCursor; - text_view_class->paste_clipboard = PasteClipboard; - text_view_class->set_anchor = SetAnchor; - text_view_class->toggle_overwrite = ToggleOverwrite; + klass->backspace = BackSpace; + klass->copy_clipboard = CopyClipboard; + klass->cut_clipboard = CutClipboard; + klass->delete_from_cursor = DeleteFromCursor; + klass->insert_at_cursor = InsertAtCursor; + klass->move_cursor = MoveCursor; + klass->paste_clipboard = PasteClipboard; + klass->set_anchor = SetAnchor; + klass->toggle_overwrite = ToggleOverwrite; // "move-focus", "move-viewport", "select-all" and "toggle-cursor-visible" // have no corresponding virtual methods. Since glib 2.18 (gtk 2.14), diff --git a/chromium/ui/gtk/gtk_key_bindings_handler.h b/chromium/ui/gtk/gtk_key_bindings_handler.h index afd795a4471..f3c3831cf18 100644 --- a/chromium/ui/gtk/gtk_key_bindings_handler.h +++ b/chromium/ui/gtk/gtk_key_bindings_handler.h @@ -5,14 +5,12 @@ #ifndef UI_GTK_GTK_KEY_BINDINGS_HANDLER_H_ #define UI_GTK_GTK_KEY_BINDINGS_HANDLER_H_ -#include <gtk/gtk.h> - #include <string> #include <vector> #include "ui/base/ime/linux/text_edit_command_auralinux.h" #include "ui/events/platform_event.h" -#include "ui/gtk/gtk_types.h" +#include "ui/gtk/gtk_compat.h" namespace ui { class Event; @@ -52,13 +50,57 @@ class GtkKeyBindingsHandler { private: // Object structure of Handler class, which is derived from GtkTextView. struct Handler { - GtkTextView parent_object; + // Starting in Gtk4, GtkTextView subclasses from GtkWidget instead of + // GtkContainer. This class is only used on Gtk3, so to ensure ABI + // compatibility, we always want the Gtk3 struct layout even when building + // with Gtk4 headers. To facilitate this, we manually copy the class + // hierarchy up to GtkWidget. + GtkWidget widget; + void* container_private; + void* text_view_private; GtkKeyBindingsHandler* owner; }; // Class structure of Handler class. struct HandlerClass { - GtkTextViewClass parent_class; + // Class layout for types changes between GTK versions, but is stable within + // the same major version. This class is only used on Gtk3, so manually + // expand the class layout as it appears in Gtk3. + GInitiallyUnownedClass parent_class; + + // GtkWidgetClass and GtkContainerClass + guint pad0; + void* pad1[95]; + unsigned int pad2 : 1; + void* pad3[8]; + + // GtkTextViewClass + void (*populate_popup)(GtkTextView* text_view, GtkWidget* popup); + void (*move_cursor)(GtkTextView* text_view, + GtkMovementStep step, + gint count, + gboolean extend_selection); + void (*set_anchor)(GtkTextView* text_view); + void (*insert_at_cursor)(GtkTextView* text_view, const gchar* str); + void (*delete_from_cursor)(GtkTextView* text_view, + GtkDeleteType type, + gint count); + void (*backspace)(GtkTextView* text_view); + void (*cut_clipboard)(GtkTextView* text_view); + void (*copy_clipboard)(GtkTextView* text_view); + void (*paste_clipboard)(GtkTextView* text_view); + void (*toggle_overwrite)(GtkTextView* text_view); + GtkTextBuffer* (*create_buffer)(GtkTextView* text_view); + void (*draw_layer)(GtkTextView* text_view, + GtkTextViewLayer layer, + cairo_t* cr); + gboolean (*extend_selection)(GtkTextView* text_view, + GtkTextExtendSelection granularity, + const GtkTextIter* location, + GtkTextIter* start, + GtkTextIter* end); + void (*insert_emoji)(GtkTextView* text_view); + void* pad4[4]; }; // Creates a new instance of Handler class. diff --git a/chromium/ui/gtk/gtk_types.h b/chromium/ui/gtk/gtk_types.h index a891983fdf0..32ac5cddde1 100644 --- a/chromium/ui/gtk/gtk_types.h +++ b/chromium/ui/gtk/gtk_types.h @@ -6,13 +6,15 @@ #define UI_GTK_GTK_TYPES_H_ #include <gdk/gdk.h> - -#include "ui/gtk/gtk_buildflags.h" +#include <gtk/gtk.h> // This file provides types that are only available in specific versions of GTK. +// This struct uses doubles in Gtk3, but floats in Gtk4. +#define GdkRGBA Do_not_use_GdkRGBA_because_it_is_not_ABI_compatible + extern "C" { -#if BUILDFLAG(GTK_VERSION) == 3 +#if GTK_MAJOR_VERSION == 3 using GskRenderNodeType = enum { GSK_NOT_A_RENDER_NODE = 0, GSK_CONTAINER_NODE, @@ -52,10 +54,12 @@ using GtkSnapshot = GdkSnapshot; using GdkPaintable = struct _GdkPaintable; using GtkNative = struct _GtkNative; using GdkSurface = struct _GdkSurface; +using GdkToplevel = struct _GdkToplevel; constexpr GdkMemoryFormat GDK_MEMORY_B8G8R8A8 = static_cast<GdkMemoryFormat>(3); -#else +#elif GTK_MAJOR_VERSION == 4 enum GtkWidgetHelpType : int; +enum GtkWindowType : int; using GtkWidgetPath = struct _GtkWidgetPath; using GtkContainer = struct _GtkContainer; @@ -64,6 +68,9 @@ using GdkWindow = struct _GdkWindow; using GdkKeymap = struct _GdkKeymap; using GtkIconInfo = struct _GtkIconInfo; using GdkScreen = struct _GdkScreen; +using GdkColor = struct _GdkColor; + +using GdkEventFunc = void (*)(GdkEvent* event, gpointer data); struct _GdkEventKey { GdkEventType type; @@ -79,11 +86,20 @@ struct _GdkEventKey { guint is_modifier : 1; }; +struct _GdkColor { + guint32 pixel; + guint16 red; + guint16 green; + guint16 blue; +}; + constexpr int GTK_ICON_LOOKUP_USE_BUILTIN = 1 << 2; constexpr int GTK_ICON_LOOKUP_GENERIC_FALLBACK = 1 << 3; constexpr int GTK_ICON_LOOKUP_FORCE_SIZE = 1 << 4; -constexpr const char GTK_STYLE_PROPERTY_BACKGROUND_IMAGE[] = "background-image"; +constexpr auto GTK_WINDOW_TOPLEVEL = static_cast<GtkWindowType>(0); +#else +#error "Unsupported GTK version" #endif } diff --git a/chromium/ui/gtk/gtk_ui.cc b/chromium/ui/gtk/gtk_ui.cc index b99afd66e79..3c7fe071cda 100644 --- a/chromium/ui/gtk/gtk_ui.cc +++ b/chromium/ui/gtk/gtk_ui.cc @@ -5,8 +5,6 @@ #include "ui/gtk/gtk_ui.h" #include <cairo.h> -#include <gdk/gdk.h> -#include <gdk/gdkkeysyms.h> #include <pango/pango.h> #include <cmath> @@ -23,9 +21,8 @@ #include "base/nix/xdg_util.h" #include "base/stl_util.h" #include "base/strings/string_split.h" -#include "base/strings/stringprintf.h" #include "chrome/browser/themes/theme_properties.h" // nogncheck -#include "printing/buildflags/buildflags.h" +#include "printing/buildflags/buildflags.h" // nogncheck #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColor.h" @@ -35,6 +32,7 @@ #include "ui/base/ime/linux/fake_input_method_context.h" #include "ui/base/ime/linux/linux_input_method_context.h" #include "ui/base/ime/linux/linux_input_method_context_factory.h" +#include "ui/base/linux/linux_ui_delegate.h" #include "ui/display/display.h" #include "ui/events/keycodes/dom/dom_code.h" #include "ui/events/keycodes/dom/dom_keyboard_layout_manager.h" @@ -49,7 +47,7 @@ #include "ui/gfx/skia_util.h" #include "ui/gtk/gtk_compat.h" #include "ui/gtk/gtk_key_bindings_handler.h" -#include "ui/gtk/gtk_ui_delegate.h" +#include "ui/gtk/gtk_ui_platform.h" #include "ui/gtk/gtk_util.h" #include "ui/gtk/input_method_context_impl_gtk.h" #include "ui/gtk/native_theme_gtk.h" @@ -74,13 +72,28 @@ #if defined(USE_OZONE) #include "ui/base/ime/input_method.h" #include "ui/base/ui_base_features.h" +#include "ui/ozone/buildflags.h" #include "ui/ozone/public/ozone_platform.h" +#if BUILDFLAG(OZONE_PLATFORM_WAYLAND) +#define USE_WAYLAND +#endif +#if BUILDFLAG(OZONE_PLATFORM_X11) && !defined(USE_X11) +#define USE_X11 +#endif #endif #if BUILDFLAG(ENABLE_PRINTING) #include "printing/printing_context_linux.h" #endif +#if defined(USE_WAYLAND) +#include "ui/gtk/wayland/gtk_ui_platform_wayland.h" +#endif + +#if defined(USE_X11) +#include "ui/gtk/x/gtk_ui_platform_x11.h" +#endif + namespace gtk { namespace { @@ -284,23 +297,38 @@ views::LinuxUI::WindowFrameAction GetDefaultMiddleClickAction() { } } +std::unique_ptr<GtkUiPlatform> CreateGtkUiPlatform(ui::LinuxUiBackend backend) { + switch (backend) { +#if defined(USE_X11) + case ui::LinuxUiBackend::kX11: + return std::make_unique<GtkUiPlatformX11>(); +#endif +#if defined(USE_WAYLAND) + case ui::LinuxUiBackend::kWayland: + return std::make_unique<GtkUiPlatformWayland>(); +#endif + default: + NOTREACHED(); + return nullptr; + } +} + } // namespace -GtkUi::GtkUi(ui::GtkUiDelegate* delegate) : delegate_(delegate) { +GtkUi::GtkUi() { using Action = views::LinuxUI::WindowFrameAction; using ActionSource = views::LinuxUI::WindowFrameActionSource; - DCHECK(delegate_); DCHECK(!g_gtk_ui); g_gtk_ui = this; - window_frame_actions_ = { - {ActionSource::kDoubleClick, Action::kToggleMaximize}, - {ActionSource::kMiddleClick, GetDefaultMiddleClickAction()}, - {ActionSource::kRightClick, Action::kMenu}}; + CHECK(LoadGtk()); - static bool loaded = LoadGtk(BUILDFLAG(GTK_VERSION)); - CHECK(loaded); + auto* delegate = ui::LinuxUiDelegate::GetInstance(); + // TODO(thomasanderson): This should be replaced with DCHECK(delegate) once + // fully migrated to ozone. + auto backend = delegate ? delegate->GetBackend() : ui::LinuxUiBackend::kX11; + platform_ = CreateGtkUiPlatform(backend); // Avoid GTK initializing atk-bridge, and let AuraLinux implementation // do it once it is ready. @@ -308,15 +336,22 @@ GtkUi::GtkUi(ui::GtkUiDelegate* delegate) : delegate_(delegate) { env->SetVar("NO_AT_BRIDGE", "1"); GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); native_theme_ = NativeThemeGtk::instance(); + + window_frame_actions_ = { + {ActionSource::kDoubleClick, Action::kToggleMaximize}, + {ActionSource::kMiddleClick, GetDefaultMiddleClickAction()}, + {ActionSource::kRightClick, Action::kMenu}}; } GtkUi::~GtkUi() { + DCHECK_EQ(g_gtk_ui, this); g_gtk_ui = nullptr; } -ui::GtkUiDelegate* GtkUi::GetDelegate() { +// static +GtkUiPlatform* GtkUi::GetPlatform() { DCHECK(g_gtk_ui) << "GtkUi instance is not set."; - return g_gtk_ui->delegate_; + return g_gtk_ui->platform_.get(); } void GtkUi::Initialize() { @@ -374,7 +409,7 @@ void GtkUi::Initialize() { indicators_count = 0; - GetDelegate()->OnInitialized(GetDummyWindow()); + platform_->OnInitialized(GetDummyWindow()); } bool GtkUi::GetTint(int id, color_utils::HSL* tint) const { @@ -782,7 +817,7 @@ bool GtkUi::MatchEvent(const ui::Event& event, // determine if GtkUi's key binding handling implementation is used or not. // Ozone/Wayland was unintentionally using GtkUi for keybinding handling, so // early out here, for now, until a proper solution for ozone is implemented. - if (!GetDelegate()->GetGdkKeymap()) + if (!platform_->GetGdkKeymap()) return false; // Ensure that we have a keyboard handler. @@ -1073,7 +1108,3 @@ float GtkUi::GetDeviceScaleFactor() const { } } // namespace gtk - -views::LinuxUI* BuildGtkUi(ui::GtkUiDelegate* delegate) { - return new gtk::GtkUi(delegate); -} diff --git a/chromium/ui/gtk/gtk_ui.h b/chromium/ui/gtk/gtk_ui.h index 3cb1c8df374..e4ecb6e3640 100644 --- a/chromium/ui/gtk/gtk_ui.h +++ b/chromium/ui/gtk/gtk_ui.h @@ -10,12 +10,11 @@ #include <vector> #include "base/compiler_specific.h" -#include "base/component_export.h" #include "base/macros.h" #include "base/observer_list.h" #include "ui/base/glib/glib_signal.h" #include "ui/gfx/color_utils.h" -#include "ui/gtk/gtk_ui_delegate.h" +#include "ui/gtk/gtk_ui_platform.h" #include "ui/views/linux_ui/linux_ui.h" #include "ui/views/window/frame_buttons.h" @@ -35,12 +34,12 @@ class SettingsProvider; // Interface to GTK desktop features. class GtkUi : public views::LinuxUI { public: - explicit GtkUi(ui::GtkUiDelegate* delegate); + GtkUi(); ~GtkUi() override; // Static delegate getter, used by different objects (created by GtkUi), e.g: // Dialogs, IME Context, when platform-specific functionality is required. - static ui::GtkUiDelegate* GetDelegate(); + static GtkUiPlatform* GetPlatform(); // Setters used by SettingsProvider: void SetWindowButtonOrdering( @@ -146,8 +145,7 @@ class GtkUi : public views::LinuxUI { float GetRawDeviceScaleFactor(); - // Not owned by GtkUi. - ui::GtkUiDelegate* const delegate_; + std::unique_ptr<GtkUiPlatform> platform_; NativeThemeGtk* native_theme_; @@ -214,8 +212,4 @@ class GtkUi : public views::LinuxUI { } // namespace gtk -// Access point to the GTK desktop system. -COMPONENT_EXPORT(GTK) -views::LinuxUI* BuildGtkUi(ui::GtkUiDelegate* delegate); - #endif // UI_GTK_GTK_UI_H_ diff --git a/chromium/ui/gtk/gtk_ui_delegate.cc b/chromium/ui/gtk/gtk_ui_delegate.cc deleted file mode 100644 index 9936e87daab..00000000000 --- a/chromium/ui/gtk/gtk_ui_delegate.cc +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/gtk/gtk_ui_delegate.h" - -namespace ui { - -namespace { - -GtkUiDelegate* g_gtk_ui_delegate = nullptr; - -} // namespace - -void GtkUiDelegate::SetInstance(GtkUiDelegate* instance) { - g_gtk_ui_delegate = instance; -} - -GtkUiDelegate* GtkUiDelegate::instance() { - return g_gtk_ui_delegate; -} - -} // namespace ui diff --git a/chromium/ui/gtk/gtk_ui_factory.cc b/chromium/ui/gtk/gtk_ui_factory.cc new file mode 100644 index 00000000000..06cd8306a98 --- /dev/null +++ b/chromium/ui/gtk/gtk_ui_factory.cc @@ -0,0 +1,11 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gtk/gtk_ui_factory.h" + +#include "ui/gtk/gtk_ui.h" + +std::unique_ptr<views::LinuxUI> BuildGtkUi() { + return std::make_unique<gtk::GtkUi>(); +} diff --git a/chromium/ui/gtk/gtk_ui_factory.h b/chromium/ui/gtk/gtk_ui_factory.h new file mode 100644 index 00000000000..f0766020c4a --- /dev/null +++ b/chromium/ui/gtk/gtk_ui_factory.h @@ -0,0 +1,21 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GTK_GTK_UI_FACTORY_H_ +#define UI_GTK_GTK_UI_FACTORY_H_ + +#include <memory> + +#include "base/component_export.h" + +namespace views { +class LinuxUI; +} + +// Access point to the GTK desktop system. This should be the only symbol +// exported from this component. +COMPONENT_EXPORT(GTK) +std::unique_ptr<views::LinuxUI> BuildGtkUi(); + +#endif // UI_GTK_GTK_UI_FACTORY_H_ diff --git a/chromium/ui/gtk/gtk_ui_delegate.h b/chromium/ui/gtk/gtk_ui_platform.h index 07a50008199..8650770cd8c 100644 --- a/chromium/ui/gtk/gtk_ui_delegate.h +++ b/chromium/ui/gtk/gtk_ui_platform.h @@ -2,39 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_GTK_GTK_UI_DELEGATE_H_ -#define UI_GTK_GTK_UI_DELEGATE_H_ +#ifndef UI_GTK_GTK_UI_PLATFORM_H_ +#define UI_GTK_GTK_UI_PLATFORM_H_ -#include "base/component_export.h" #include "ui/gfx/native_widget_types.h" -#include "ui/gtk/gtk_buildflags.h" using GdkKeymap = struct _GdkKeymap; using GtkWindow = struct _GtkWindow; using GtkWidget = struct _GtkWidget; using GdkWindow = struct _GdkWindow; -namespace ui { +namespace gtk { -// GtkUiDelegate encapsulates platform-specific functionalities required by -// a Gtk-based LinuxUI implementation. The main goal of this interface is to -// make GtkUi platform agnostic, moving the platform specifics to lower level -// layers (e.g: ozone). Linux backends (e.g: ozone/x11, aura/x11, ozone/wayland) -// must provide a GtkUiDelegate implementation and inject its singleton instance -// of it via |SetInstance| in order to be able to use GtkUi. -class COMPONENT_EXPORT(GTK) GtkUiDelegate { +// GtkUiPlatform encapsulates platform-specific functionalities required by +// a Gtk-based LinuxUI implementation. +class GtkUiPlatform { public: - virtual ~GtkUiDelegate() = default; - - // Sets the singleton delegate instance to be used by GtkUi. This makes it - // possible for ozone-based backends, for example, to inject the GtkUiDelegate - // object without polluting Ozone API, since just a small subset of ozone - // backends make use of GtkUi. This pointer is not owned, and if this method - // is called a second time, the first instance is not deleted. - static void SetInstance(GtkUiDelegate* instance); - - // Returns the current active instance. - static GtkUiDelegate* instance(); + virtual ~GtkUiPlatform() = default; // Called when the GtkUi instance initialization process finished. |widget| is // a dummy window passed in for context. @@ -63,6 +47,6 @@ class COMPONENT_EXPORT(GTK) GtkUiDelegate { virtual int GetGdkKeyState() = 0; }; -} // namespace ui +} // namespace gtk -#endif // UI_GTK_GTK_UI_DELEGATE_H_ +#endif // UI_GTK_GTK_UI_PLATFORM_H_ diff --git a/chromium/ui/gtk/gtk_util.cc b/chromium/ui/gtk/gtk_util.cc index 2bf77787479..fd08941211a 100644 --- a/chromium/ui/gtk/gtk_util.cc +++ b/chromium/ui/gtk/gtk_util.cc @@ -4,8 +4,6 @@ #include "ui/gtk/gtk_util.h" -#include <gdk/gdk.h> -#include <gtk/gtk.h> #include <locale.h> #include <stddef.h> @@ -27,8 +25,9 @@ #include "ui/gfx/color_utils.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/native_widget_types.h" +#include "ui/gtk/gtk_compat.h" #include "ui/gtk/gtk_ui.h" -#include "ui/gtk/gtk_ui_delegate.h" +#include "ui/gtk/gtk_ui_platform.h" #include "ui/native_theme/common_theme.h" #include "ui/ozone/public/ozone_platform.h" #include "ui/views/linux_ui/linux_ui.h" @@ -37,16 +36,6 @@ using base::StrCat; namespace gtk { -#if BUILDFLAG(GTK_VERSION) >= 4 -const char kGtkCSSMenu[] = "#popover.background.menu #contents"; -const char kGtkCSSMenuItem[] = "#modelbutton.flat"; -const char kGtkCSSMenuScrollbar[] = "#scrollbar #range"; -#else -const char kGtkCSSMenu[] = "GtkMenu#menu"; -const char kGtkCSSMenuItem[] = "GtkMenuItem#menuitem"; -const char kGtkCSSMenuScrollbar[] = "GtkScrollbar#scrollbar #trough"; -#endif - namespace { const char kAuraTransientParent[] = "aura-transient-parent"; @@ -161,17 +150,27 @@ GtkCssContext AppendCssNodeToStyleContextImpl( } GtkWidget* CreateDummyWindow() { -#if BUILDFLAG(GTK_VERSION) >= 4 - GtkWidget* window = gtk_window_new(); -#else - GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL); -#endif + GtkWidget* window = GtkToplevelWindowNew(); gtk_widget_realize(window); return window; } } // namespace +const char* GtkCssMenu() { + return GtkCheckVersion(4) ? "#popover.background.menu #contents" + : "GtkMenu#menu"; +} + +const char* GtkCssMenuItem() { + return GtkCheckVersion(4) ? "#modelbutton.flat" : "GtkMenuItem#menuitem"; +} + +const char* GtkCssMenuScrollbar() { + return GtkCheckVersion(4) ? "#scrollbar #range" + : "GtkScrollbar#scrollbar #trough"; +} + void GtkInitFromCommandLine(const base::CommandLine& command_line) { CommonInitFromCommandLine(command_line); } @@ -182,7 +181,7 @@ void SetGtkTransientForAura(GtkWidget* dialog, aura::Window* parent) { gtk_widget_realize(dialog); gfx::AcceleratedWidget parent_id = parent->GetHost()->GetAcceleratedWidget(); - GtkUi::GetDelegate()->SetGtkWidgetTransientFor(dialog, parent_id); + GtkUi::GetPlatform()->SetGtkWidgetTransientFor(dialog, parent_id); // We also set the |parent| as a property of |dialog|, so that we can unlink // the two later. @@ -196,7 +195,7 @@ aura::Window* GetAuraTransientParent(GtkWidget* dialog) { void ClearAuraTransientParent(GtkWidget* dialog, aura::Window* parent) { g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, nullptr); - GtkUi::GetDelegate()->ClearTransientFor( + GtkUi::GetPlatform()->ClearTransientFor( parent->GetHost()->GetAcceleratedWidget()); } @@ -337,11 +336,6 @@ GtkStateFlags StateToStateFlags(ui::NativeTheme::State state) { } } -SkColor GdkRgbaToSkColor(const GdkRGBA& color) { - return SkColorSetARGB(color.alpha * 255, color.red * 255, color.green * 255, - color.blue * 255); -} - NO_SANITIZE("cfi-icall") GtkCssContext AppendCssNodeToStyleContext(GtkCssContext context, const std::string& css_node) { @@ -408,10 +402,10 @@ GtkCssContext AppendCssNodeToStyleContext(GtkCssContext context, object_name = t.token(); break; case CSS_TYPE: { -#if BUILDFLAG(GTK_VERSION) < 4 - gtype = g_type_from_name(t.token().c_str()); - DCHECK(gtype); -#endif + if (!GtkCheckVersion(4)) { + gtype = g_type_from_name(t.token().c_str()); + DCHECK(gtype); + } break; } case CSS_CLASS: @@ -457,17 +451,6 @@ GtkCssContext GetStyleContextFromCss(const std::string& css_selector) { return context; } -SkColor GetFgColorFromStyleContext(GtkStyleContext* context) { - GdkRGBA color; -#if BUILDFLAG(GTK_VERSION) >= 4 - gtk_style_context_get_color(context, &color); -#else - gtk_style_context_get_color(context, gtk_style_context_get_state(context), - &color); -#endif - return GdkRgbaToSkColor(color); -} - SkColor GetBgColorFromStyleContext(GtkCssContext context) { // Backgrounds are more general than solid colors (eg. gradients), // but chromium requires us to boil this down to one color. We @@ -488,18 +471,12 @@ SkColor GetBgColorFromStyleContext(GtkCssContext context) { } SkColor GetFgColor(const std::string& css_selector) { - return GetFgColorFromStyleContext(GetStyleContextFromCss(css_selector)); + return GtkStyleContextGetColor(GetStyleContextFromCss(css_selector)); } ScopedCssProvider GetCssProvider(const std::string& css) { auto provider = TakeGObject(gtk_css_provider_new()); -#if BUILDFLAG(GTK_VERSION) >= 4 - gtk_css_provider_load_from_data(provider, css.c_str(), -1); -#else - GError* error = nullptr; - gtk_css_provider_load_from_data(provider, css.c_str(), -1, &error); - DCHECK(!error); -#endif + GtkCssProviderLoadFromData(provider, css.c_str(), -1); return provider; } @@ -544,28 +521,19 @@ SkColor GetSelectionBgColor(const std::string& css_selector) { auto context = GetStyleContextFromCss(css_selector); if (GtkCheckVersion(3, 20)) return GetBgColorFromStyleContext(context); -#if BUILDFLAG(GTK_VERSION) < 4 - // This is verbatim how Gtk gets the selection color on versions before 3.20. - GdkRGBA selection_color; - G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - gtk_style_context_get_background_color( - context, gtk_style_context_get_state(context), &selection_color); - G_GNUC_END_IGNORE_DEPRECATIONS; - return GdkRgbaToSkColor(selection_color); -#else - NOTREACHED(); - return gfx::kPlaceholderColor; -#endif + DCHECK(!GtkCheckVersion(4)); + // This is verbatim how Gtk gets the selection color on versions + // before 3.20. + return GtkStyleContextGetBackgroundColor(context); } bool ContextHasClass(GtkCssContext context, const std::string& style_class) { -#if BUILDFLAG(GTK_VERSION) >= 4 - return gtk_style_context_has_class(context, style_class.c_str()); -#else - return gtk_style_context_has_class(context, style_class.c_str()) || - gtk_widget_path_iter_has_class(gtk_style_context_get_path(context), -1, - style_class.c_str()); -#endif + bool has_class = gtk_style_context_has_class(context, style_class.c_str()); + if (!GtkCheckVersion(4)) { + has_class |= gtk_widget_path_iter_has_class( + gtk_style_context_get_path(context), -1, style_class.c_str()); + } + return has_class; } SkColor GetSeparatorColor(const std::string& css_selector) { @@ -576,22 +544,17 @@ SkColor GetSeparatorColor(const std::string& css_selector) { bool horizontal = ContextHasClass(context, "horizontal"); int w = 1, h = 1; - GtkBorder border, padding; -#if BUILDFLAG(GTK_VERSION) >= 4 - auto size = GetSeparatorSize(horizontal); - w = size.width(); - h = size.height(); - gtk_style_context_get_border(context, &border); - gtk_style_context_get_padding(context, &padding); -#else - gtk_style_context_get(context, gtk_style_context_get_state(context), - "min-width", &w, "min-height", &h, nullptr); - GtkStateFlags state = gtk_style_context_get_state(context); - gtk_style_context_get_border(context, state, &border); - gtk_style_context_get_padding(context, state, &padding); -#endif - w += border.left + padding.left + padding.right + border.right; - h += border.top + padding.top + padding.bottom + border.bottom; + if (GtkCheckVersion(4)) { + auto size = GetSeparatorSize(horizontal); + w = size.width(); + h = size.height(); + } else { + GtkStyleContextGet(context, "min-width", &w, "min-height", &h, nullptr); + } + auto border = GtkStyleContextGetBorder(context); + auto padding = GtkStyleContextGetPadding(context); + w += border.left() + padding.left() + padding.right() + border.right(); + h += border.top() + padding.top() + padding.bottom() + border.bottom(); if (horizontal) { w = 24; @@ -646,7 +609,7 @@ GdkModifierType GetGdkKeyEventState(const ui::KeyEvent& key_event) { // In such a case there is no event being dispatching in the display // backend. state = static_cast<GdkModifierType>( - state | ui::GtkUiDelegate::instance()->GetGdkKeyState()); + state | GtkUi::GetPlatform()->GetGdkKeyState()); } return state; @@ -655,13 +618,13 @@ GdkModifierType GetGdkKeyEventState(const ui::KeyEvent& key_event) { GdkEvent* GdkEventFromKeyEvent(const ui::KeyEvent& key_event) { DCHECK(!GtkCheckVersion(4)); GdkEventType event_type = - key_event.type() == ui::ET_KEY_PRESSED ? GDK_KEY_PRESS : GDK_KEY_RELEASE; + key_event.type() == ui::ET_KEY_PRESSED ? GdkKeyPress() : GdkKeyRelease(); auto event_time = key_event.time_stamp() - base::TimeTicks(); int hw_code = GetKeyEventProperty(key_event, ui::kPropertyKeyboardHwKeyCode); int group = GetKeyEventProperty(key_event, ui::kPropertyKeyboardGroup); // Get GdkKeymap - GdkKeymap* keymap = GtkUi::GetDelegate()->GetGdkKeymap(); + GdkKeymap* keymap = GtkUi::GetPlatform()->GetGdkKeymap(); // Get keyval and state GdkModifierType state = GetGdkKeyEventState(key_event); @@ -690,19 +653,16 @@ GdkEvent* GdkEventFromKeyEvent(const ui::KeyEvent& key_event) { } GtkIconTheme* GetDefaultIconTheme() { -#if BUILDFLAG(GTK_VERSION) >= 4 - return gtk_icon_theme_get_for_display(gdk_display_get_default()); -#else - return gtk_icon_theme_get_default(); -#endif + return GtkCheckVersion(4) + ? gtk_icon_theme_get_for_display(gdk_display_get_default()) + : gtk_icon_theme_get_default(); } void GtkWindowDestroy(GtkWidget* widget) { -#if BUILDFLAG(GTK_VERSION) >= 4 - gtk_window_destroy(GTK_WINDOW(widget)); -#else - gtk_widget_destroy(widget); -#endif + if (GtkCheckVersion(4)) + gtk_window_destroy(GTK_WINDOW(widget)); + else + gtk_widget_destroy(widget); } GtkWidget* GetDummyWindow() { @@ -776,7 +736,7 @@ GdkTexture* GetTextureFromRenderNode(GskRenderNode* node) { // TODO(tluk): Refactor this to make better use of the hierarchical nature of // ColorPipeline. -base::Optional<SkColor> SkColorFromColorId(ui::ColorId color_id) { +absl::optional<SkColor> SkColorFromColorId(ui::ColorId color_id) { switch (color_id) { case ui::kColorWindowBackground: case ui::kColorDialogBackground: @@ -787,11 +747,13 @@ base::Optional<SkColor> SkColorFromColorId(ui::ColorId color_id) { case ui::kColorAvatarIconIncognito: return GetFgColor("GtkLabel#label"); case ui::kColorBubbleFooterBackground: + case ui::kColorSyncInfoBackground: + return GetBgColor("#statusbar"); case ui::kColorNotificationActionsBackground: case ui::kColorNotificationBackgroundActive: case ui::kColorNotificationImageBackground: - case ui::kColorSyncInfoBackground: - return GetBgColor("#statusbar"); + return color_utils::BlendTowardMaxContrast(GetBgColor(""), + gfx::kGoogleGreyAlpha100); // FocusableBorder case ui::kColorFocusableBorderFocused: @@ -814,60 +776,61 @@ base::Optional<SkColor> SkColorFromColorId(ui::ColorId color_id) { case ui::kColorMenuItemBackgroundAlertedInitial: case ui::kColorMenuItemBackgroundAlertedTarget: case ui::kColorSubtleEmphasisBackground: - return GetBgColor(kGtkCSSMenu); + return GetBgColor(GtkCssMenu()); case ui::kColorMenuBorder: - return GetBorderColor(kGtkCSSMenu); + return GetBorderColor(GtkCssMenu()); case ui::kColorMenuItemBackgroundSelected: - return GetBgColor(StrCat({kGtkCSSMenu, " ", kGtkCSSMenuItem, ":hover"})); + return GetBgColor( + StrCat({GtkCssMenu(), " ", GtkCssMenuItem(), ":hover"})); case ui::kColorMenuItemForeground: case ui::kColorMenuDropmarker: case ui::kColorMenuItemForegroundHighlighted: return GetFgColor( - StrCat({kGtkCSSMenu, " ", kGtkCSSMenuItem, " GtkLabel#label"})); + StrCat({GtkCssMenu(), " ", GtkCssMenuItem(), " GtkLabel#label"})); case ui::kColorMenuItemForegroundSelected: - return GetFgColor( - StrCat({kGtkCSSMenu, " ", kGtkCSSMenuItem, ":hover GtkLabel#label"})); + return GetFgColor(StrCat( + {GtkCssMenu(), " ", GtkCssMenuItem(), ":hover GtkLabel#label"})); case ui::kColorMenuItemForegroundDisabled: return GetFgColor(StrCat( - {kGtkCSSMenu, " ", kGtkCSSMenuItem, ":disabled GtkLabel#label"})); + {GtkCssMenu(), " ", GtkCssMenuItem(), ":disabled GtkLabel#label"})); case ui::kColorAvatarIconGuest: case ui::kColorMenuItemForegroundSecondary: if (GtkCheckVersion(3, 20)) { return GetFgColor( - StrCat({kGtkCSSMenu, " ", kGtkCSSMenuItem, " #accelerator"})); + StrCat({GtkCssMenu(), " ", GtkCssMenuItem(), " #accelerator"})); } - return GetFgColor(StrCat( - {kGtkCSSMenu, " ", kGtkCSSMenuItem, " GtkLabel#label.accelerator"})); + return GetFgColor(StrCat({GtkCssMenu(), " ", GtkCssMenuItem(), + " GtkLabel#label.accelerator"})); case ui::kColorMenuSeparator: case ui::kColorAvatarHeaderArt: if (GtkCheckVersion(3, 20)) { return GetSeparatorColor( - StrCat({kGtkCSSMenu, " GtkSeparator#separator.horizontal"})); + StrCat({GtkCssMenu(), " GtkSeparator#separator.horizontal"})); } return GetFgColor( - StrCat({kGtkCSSMenu, " ", kGtkCSSMenuItem, ".separator"})); + StrCat({GtkCssMenu(), " ", GtkCssMenuItem(), ".separator"})); // Dropdown case ui::kColorDropdownBackground: return GetBgColor( StrCat({"GtkComboBoxText#combobox GtkWindow#window.background.popup ", - "GtkTreeMenu#menu(gtk-combobox-popup-menu) ", kGtkCSSMenuItem, - " ", "GtkCellView#cellview"})); + "GtkTreeMenu#menu(gtk-combobox-popup-menu) ", + GtkCssMenuItem(), " ", "GtkCellView#cellview"})); case ui::kColorDropdownForeground: return GetFgColor( StrCat({"GtkComboBoxText#combobox GtkWindow#window.background.popup ", - "GtkTreeMenu#menu(gtk-combobox-popup-menu) ", kGtkCSSMenuItem, - " ", "GtkCellView#cellview"})); + "GtkTreeMenu#menu(gtk-combobox-popup-menu) ", + GtkCssMenuItem(), " ", "GtkCellView#cellview"})); case ui::kColorDropdownBackgroundSelected: return GetBgColor( StrCat({"GtkComboBoxText#combobox GtkWindow#window.background.popup ", - "GtkTreeMenu#menu(gtk-combobox-popup-menu) ", kGtkCSSMenuItem, - ":hover GtkCellView#cellview"})); + "GtkTreeMenu#menu(gtk-combobox-popup-menu) ", + GtkCssMenuItem(), ":hover GtkCellView#cellview"})); case ui::kColorDropdownForegroundSelected: return GetFgColor( StrCat({"GtkComboBoxText#combobox GtkWindow#window.background.popup ", - "GtkTreeMenu#menu(gtk-combobox-popup-menu) ", kGtkCSSMenuItem, - ":hover GtkCellView#cellview"})); + "GtkTreeMenu#menu(gtk-combobox-popup-menu) ", + GtkCssMenuItem(), ":hover GtkCellView#cellview"})); // Label case ui::kColorLabelForeground: @@ -898,22 +861,20 @@ base::Optional<SkColor> SkColorFromColorId(ui::ColorId color_id) { case ui::kColorLinkForeground: { if (GtkCheckVersion(3, 12)) return GetFgColor("GtkLabel#label.link:link"); -#if BUILDFLAG(GTK_VERSION) < 4 auto link_context = GetStyleContextFromCss("GtkLabel#label.view"); - GdkColor* color; - gtk_style_context_get_style(link_context, "link-color", &color, nullptr); + GdkColor* color = nullptr; + GtkStyleContextGetStyle(link_context, "link-color", &color, nullptr); if (color) { SkColor ret_color = SkColorSetRGB(color->red >> 8, color->green >> 8, color->blue >> 8); // gdk_color_free() was deprecated in Gtk3.14. This code path is only - // taken on versions earlier than Gtk3.12, but the compiler doesn't know - // that, so silence the deprecation warnings. + // taken on versions earlier than Gtk3.12, but the compiler doesn't + // know that, so silence the deprecation warnings. G_GNUC_BEGIN_IGNORE_DEPRECATIONS; gdk_color_free(color); G_GNUC_END_IGNORE_DEPRECATIONS; return ret_color; } -#endif // Default color comes from gtklinkbutton.c. return SkColorSetRGB(0x00, 0x00, 0xEE); } @@ -1010,12 +971,10 @@ base::Optional<SkColor> SkColorFromColorId(ui::ColorId color_id) { return GetBgColor(GtkCheckVersion(3, 20) ? "GtkTextView#textview.view" : "GtkTextView.view"); case ui::kColorTextfieldForegroundPlaceholder: - if (!GtkCheckVersion(3, 90)) { + if (!GtkCheckVersion(4)) { auto context = GetStyleContextFromCss("GtkEntry#entry"); // This is copied from gtkentry.c. - GdkRGBA fg = {0.5, 0.5, 0.5}; - gtk_style_context_lookup_color(context, "placeholder_text_color", &fg); - return GdkRgbaToSkColor(fg); + return GtkStyleContextLookupColor(context, "placeholder_text_color"); } return GetFgColor("GtkEntry#entry #text #placeholder"); case ui::kColorTextfieldForegroundDisabled: @@ -1045,7 +1004,7 @@ base::Optional<SkColor> SkColorFromColorId(ui::ColorId color_id) { case ui::kColorTooltipForeground: { auto context = GetTooltipContext(); context = AppendCssNodeToStyleContext(context, "GtkLabel#label"); - return GetFgColorFromStyleContext(context); + return GtkStyleContextGetColor(context); } // Trees and Tables (implemented on GTK using the same class) @@ -1106,8 +1065,9 @@ base::Optional<SkColor> SkColorFromColorId(ui::ColorId color_id) { case ui::kColorMenuIcon: if (GtkCheckVersion(3, 20)) return GetFgColor( - StrCat({kGtkCSSMenu, " ", kGtkCSSMenuItem, " #radio"})); - return GetFgColor(StrCat({kGtkCSSMenu, " ", kGtkCSSMenuItem, ".radio"})); + StrCat({GtkCssMenu(), " ", GtkCssMenuItem(), " #radio"})); + return GetFgColor( + StrCat({GtkCssMenu(), " ", GtkCssMenuItem(), ".radio"})); case ui::kColorIcon: return GetFgColor("GtkButton#button.flat.scale GtkImage#image"); @@ -1115,7 +1075,7 @@ base::Optional<SkColor> SkColorFromColorId(ui::ColorId color_id) { default: break; } - return base::nullopt; + return absl::nullopt; } } // namespace gtk diff --git a/chromium/ui/gtk/gtk_util.h b/chromium/ui/gtk/gtk_util.h index 67550b1fd24..6be49077607 100644 --- a/chromium/ui/gtk/gtk_util.h +++ b/chromium/ui/gtk/gtk_util.h @@ -5,16 +5,12 @@ #ifndef UI_GTK_GTK_UTIL_H_ #define UI_GTK_GTK_UTIL_H_ -#include <gdk/gdk.h> -#include <gtk/gtk.h> - #include <string> #include <vector> #include "base/component_export.h" #include "ui/base/glib/scoped_gobject.h" #include "ui/color/color_id.h" -#include "ui/gtk/gtk_buildflags.h" #include "ui/gtk/gtk_compat.h" #include "ui/native_theme/native_theme.h" #include "ui/views/window/frame_buttons.h" @@ -33,11 +29,10 @@ class KeyEvent; namespace gtk { -extern const char kGtkCSSMenu[]; -extern const char kGtkCSSMenuItem[]; -extern const char kGtkCSSMenuScrollbar[]; +const char* GtkCssMenu(); +const char* GtkCssMenuItem(); +const char* GtkCssMenuScrollbar(); -COMPONENT_EXPORT(GTK) void GtkInitFromCommandLine(const base::CommandLine& command_line); // Sets |dialog| as transient for |parent|, which will keep it on top and center @@ -122,7 +117,6 @@ class GtkCssContext { using ScopedCssProvider = ScopedGObject<GtkCssProvider>; -#if BUILDFLAG(GTK_VERSION) < 4 } // namespace gtk // Template override cannot be in the gtk namespace. @@ -150,13 +144,10 @@ inline void ScopedGObject<GtkStyleContext>::Unref() { } namespace gtk { -#endif // Converts ui::NativeTheme::State to GtkStateFlags. GtkStateFlags StateToStateFlags(ui::NativeTheme::State state); -SkColor GdkRgbaToSkColor(const GdkRGBA& color); - // If |context| is nullptr, creates a new top-level style context // specified by parsing |css_node|. Otherwise, creates the child // context with |context| as the parent. @@ -171,8 +162,6 @@ GtkCssContext AppendCssNodeToStyleContext(GtkCssContext context, // must g_object_unref() the returned context. GtkCssContext GetStyleContextFromCss(const std::string& css_selector); -SkColor GetFgColorFromStyleContext(GtkStyleContext* context); - SkColor GetBgColorFromStyleContext(GtkCssContext context); // Overrides properties on |context| and all its parents with those @@ -249,7 +238,7 @@ float GetDeviceScaleFactor(); GdkTexture* GetTextureFromRenderNode(GskRenderNode* node); // Gets the GTK theme color for a given `color_id`. -base::Optional<SkColor> SkColorFromColorId(ui::ColorId color_id); +absl::optional<SkColor> SkColorFromColorId(ui::ColorId color_id); } // namespace gtk diff --git a/chromium/ui/gtk/input_method_context_impl_gtk.cc b/chromium/ui/gtk/input_method_context_impl_gtk.cc index 4346c07488e..74f95a1ceaf 100644 --- a/chromium/ui/gtk/input_method_context_impl_gtk.cc +++ b/chromium/ui/gtk/input_method_context_impl_gtk.cc @@ -4,10 +4,7 @@ #include "ui/gtk/input_method_context_impl_gtk.h" -#include <gdk/gdk.h> -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> -#include <stddef.h> +#include <cstddef> #include "base/strings/utf_string_conversions.h" #include "ui/aura/window_tree_host.h" @@ -21,7 +18,7 @@ #include "ui/gfx/native_widget_types.h" #include "ui/gtk/gtk_compat.h" #include "ui/gtk/gtk_ui.h" -#include "ui/gtk/gtk_ui_delegate.h" +#include "ui/gtk/gtk_ui_platform.h" #include "ui/gtk/gtk_util.h" #include "ui/views/linux_ui/linux_ui.h" @@ -32,7 +29,7 @@ namespace { GdkEventKey* GdkEventToKey(GdkEvent* event) { DCHECK(!GtkCheckVersion(4)); auto* key = reinterpret_cast<GdkEventKey*>(event); - DCHECK(key->type == GDK_KEY_PRESS || key->type == GDK_KEY_RELEASE); + DCHECK(key->type == GdkKeyPress() || key->type == GdkKeyRelease()); return key; } @@ -46,7 +43,7 @@ GdkWindow* GetTargetWindow(const ui::KeyEvent& key_event) { DCHECK(window) << "KeyEvent target window not set."; auto window_id = window->GetHost()->GetAcceleratedWidget(); - return GtkUi::GetDelegate()->GetGdkWindow(window_id); + return GtkUi::GetPlatform()->GetGdkWindow(window_id); } // Translate IME ui::KeyEvent to a GdkEventKey. diff --git a/chromium/ui/gtk/input_method_context_impl_gtk.h b/chromium/ui/gtk/input_method_context_impl_gtk.h index 2fb3356649e..c5f21cde752 100644 --- a/chromium/ui/gtk/input_method_context_impl_gtk.h +++ b/chromium/ui/gtk/input_method_context_impl_gtk.h @@ -12,7 +12,6 @@ #include "ui/base/glib/glib_signal.h" #include "ui/base/ime/linux/linux_input_method_context.h" #include "ui/gfx/geometry/rect.h" -#include "ui/gtk/gtk_buildflags.h" using GtkIMContext = struct _GtkIMContext; using GdkWindow = struct _GdkWindow; diff --git a/chromium/ui/gtk/native_theme_gtk.cc b/chromium/ui/gtk/native_theme_gtk.cc index 7efdd8cf94e..9696db767cf 100644 --- a/chromium/ui/gtk/native_theme_gtk.cc +++ b/chromium/ui/gtk/native_theme_gtk.cc @@ -4,8 +4,6 @@ #include "ui/gtk/native_theme_gtk.h" -#include <gtk/gtk.h> - #include "base/strings/strcat.h" #include "ui/color/color_provider_manager.h" #include "ui/gfx/color_palette.h" @@ -108,8 +106,7 @@ NativeThemeGtk::NativeThemeGtk() { // Initialize the GtkTreeMenu type. _gtk_tree_menu_get_type() is private, // so we need to initialize it indirectly. - auto model = - TakeGObject(GTK_TREE_MODEL(gtk_tree_store_new(1, G_TYPE_STRING))); + auto model = TakeGObject(GTK_TREE_MODEL(GtkTreeStoreNew(G_TYPE_STRING))); auto combo = TakeGObject(gtk_combo_box_new_with_model(model)); } @@ -164,11 +161,22 @@ void NativeThemeGtk::NotifyOnNativeThemeUpdated() { native_theme->NotifyOnNativeThemeUpdated(); } +std::string NativeThemeGtk::GetNativeThemeName() const { + gchar* theme = nullptr; + g_object_get(gtk_settings_get_default(), "gtk-theme-name", &theme, nullptr); + std::string theme_string; + if (theme) { + theme_string = theme; + g_free(theme); + } + return theme_string; +} + void NativeThemeGtk::OnThemeChanged(GtkSettings* settings, GtkParamSpec* param) { SetThemeCssOverride(ScopedCssProvider()); for (auto& color : color_cache_) - color = base::nullopt; + color = absl::nullopt; // Hack to workaround a bug on GNOME standard themes which would // cause black patches to be rendered on GtkFileChooser dialogs. @@ -212,15 +220,13 @@ void NativeThemeGtk::OnThemeChanged(GtkSettings* settings, bool NativeThemeGtk::AllowColorPipelineRedirection( ColorScheme color_scheme) const { - // TODO(crbug.com/1186781): Remove this override once we support NativeTheme - // changes for GTK in Color Pipeline. - return false; + return true; } SkColor NativeThemeGtk::GetSystemColorDeprecated(ColorId color_id, ColorScheme color_scheme, bool apply_processing) const { - base::Optional<SkColor> color = color_cache_[color_id]; + absl::optional<SkColor> color = color_cache_[color_id]; if (!color) { if (auto provider_color_id = ui::NativeThemeColorIdToColorId(color_id)) color = SkColorFromColorId(provider_color_id.value()); @@ -244,7 +250,7 @@ void NativeThemeGtk::PaintArrowButton( // Add the "flat" styleclass to avoid drawing a border. auto context = GetStyleContextFromCss( GtkCheckVersion(3, 20) - ? StrCat({kGtkCSSMenuScrollbar, " #range GtkButton#button.flat"}) + ? StrCat({GtkCssMenuScrollbar(), " #range GtkButton#button.flat"}) : "GtkRange.scrollbar.button.flat"); // Remove any rounded corners since arrow scrollbar buttons are tiny. ApplyCssToContext(context, "* { border-radius: 0px; }"); @@ -269,7 +275,7 @@ void NativeThemeGtk::PaintArrowButton( } PaintWidget(canvas, rect, context, BG_RENDER_NORMAL, false); - PaintArrow(canvas, rect, direction, GetFgColorFromStyleContext(context)); + PaintArrow(canvas, rect, direction, GtkStyleContextGetColor(context)); } void NativeThemeGtk::PaintScrollbarTrack( @@ -282,7 +288,7 @@ void NativeThemeGtk::PaintScrollbarTrack( PaintWidget( canvas, rect, GetStyleContextFromCss(GtkCheckVersion(3, 20) - ? StrCat({kGtkCSSMenuScrollbar, " #trough"}) + ? StrCat({GtkCssMenuScrollbar(), " #trough"}) : "GtkScrollbar.scrollbar.trough"), BG_RENDER_NORMAL, true); } @@ -296,7 +302,7 @@ void NativeThemeGtk::PaintScrollbarThumb( ColorScheme color_scheme) const { auto context = GetStyleContextFromCss( GtkCheckVersion(3, 20) - ? StrCat({kGtkCSSMenuScrollbar, " #trough #slider"}) + ? StrCat({GtkCssMenuScrollbar(), " #trough #slider"}) : "GtkScrollbar.scrollbar.slider"); gtk_style_context_set_state(context, StateToStateFlags(state)); PaintWidget(canvas, rect, context, BG_RENDER_NORMAL, true); @@ -318,7 +324,7 @@ void NativeThemeGtk::PaintMenuPopupBackground( const gfx::Size& size, const MenuBackgroundExtraParams& menu_background, ColorScheme color_scheme) const { - auto context = GetStyleContextFromCss(kGtkCSSMenu); + auto context = GetStyleContextFromCss(GtkCssMenu()); // Chrome menus aren't rendered with transparency, so avoid rounded corners. ApplyCssToContext(context, "* { border-radius: 0px; }"); PaintWidget(canvas, gfx::Rect(size), context, BG_RENDER_RECURSIVE, false); @@ -331,7 +337,7 @@ void NativeThemeGtk::PaintMenuItemBackground( const MenuItemExtraParams& menu_item, ColorScheme color_scheme) const { auto context = - GetStyleContextFromCss(StrCat({kGtkCSSMenu, " ", kGtkCSSMenuItem})); + GetStyleContextFromCss(StrCat({GtkCssMenu(), " ", GtkCssMenuItem()})); gtk_style_context_set_state(context, StateToStateFlags(state)); PaintWidget(canvas, rect, context, BG_RENDER_NORMAL, true); } @@ -365,7 +371,7 @@ void NativeThemeGtk::PaintMenuSeparator( }; if (GtkCheckVersion(3, 20)) { auto context = GetStyleContextFromCss( - StrCat({kGtkCSSMenu, " GtkSeparator#separator.horizontal"})); + StrCat({GtkCssMenu(), " GtkSeparator#separator.horizontal"})); int min_height = 1; auto margin = GtkStyleContextGetMargin(context); auto border = GtkStyleContextGetBorder(context); @@ -383,7 +389,7 @@ void NativeThemeGtk::PaintMenuSeparator( PaintWidget(canvas, gfx::Rect(x, y, w, h), context, BG_RENDER_NORMAL, true); } else { auto context = GetStyleContextFromCss( - StrCat({kGtkCSSMenu, " ", kGtkCSSMenuItem, ".separator.horizontal"})); + StrCat({GtkCssMenu(), " ", GtkCssMenuItem(), ".separator.horizontal"})); gboolean wide_separators = false; gint separator_height = 0; GtkStyleContextGetStyle(context, "wide-separators", &wide_separators, @@ -399,7 +405,7 @@ void NativeThemeGtk::PaintMenuSeparator( PaintWidget(canvas, gfx::Rect(x, y, w, h), context, BG_RENDER_NONE, true); } else { cc::PaintFlags flags; - flags.setColor(GetFgColorFromStyleContext(context)); + flags.setColor(GtkStyleContextGetColor(context)); flags.setAntiAlias(true); flags.setStrokeWidth(1); canvas->drawLine(x + 0.5f, y + 0.5f, x + w + 0.5f, y + 0.5f, flags); diff --git a/chromium/ui/gtk/native_theme_gtk.h b/chromium/ui/gtk/native_theme_gtk.h index 0d9366a3013..34d932a0163 100644 --- a/chromium/ui/gtk/native_theme_gtk.h +++ b/chromium/ui/gtk/native_theme_gtk.h @@ -6,10 +6,9 @@ #define UI_GTK_NATIVE_THEME_GTK_H_ #include "base/callback_list.h" -#include "base/component_export.h" #include "base/macros.h" #include "base/no_destructor.h" -#include "base/optional.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/base/glib/glib_signal.h" #include "ui/base/glib/scoped_gobject.h" #include "ui/native_theme/native_theme_base.h" @@ -23,7 +22,7 @@ namespace gtk { using ScopedCssProvider = ScopedGObject<GtkCssProvider>; // A version of NativeTheme that uses GTK-rendered widgets. -class COMPONENT_EXPORT(GTK) NativeThemeGtk : public ui::NativeThemeBase { +class NativeThemeGtk : public ui::NativeThemeBase { public: static NativeThemeGtk* instance(); @@ -71,6 +70,7 @@ class COMPONENT_EXPORT(GTK) NativeThemeGtk : public ui::NativeThemeBase { const FrameTopAreaExtraParams& frame_top_area, ColorScheme color_scheme) const override; void NotifyOnNativeThemeUpdated() override; + std::string GetNativeThemeName() const override; void OnThemeChanged(GtkSettings* settings, GtkParamSpec* param); @@ -89,7 +89,7 @@ class COMPONENT_EXPORT(GTK) NativeThemeGtk : public ui::NativeThemeBase { void SetThemeCssOverride(ScopedCssProvider provider); - mutable base::Optional<SkColor> color_cache_[kColorId_NumColors]; + mutable absl::optional<SkColor> color_cache_[kColorId_NumColors]; ScopedCssProvider theme_css_override_; diff --git a/chromium/ui/gtk/native_theme_gtk_unittest.cc b/chromium/ui/gtk/native_theme_gtk_unittest.cc index a19d79f564f..a415404b07e 100644 --- a/chromium/ui/gtk/native_theme_gtk_unittest.cc +++ b/chromium/ui/gtk/native_theme_gtk_unittest.cc @@ -2,20 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/gtk/native_theme_gtk.h" - +#include <memory> #include <tuple> #include "base/check.h" #include "base/command_line.h" +#include "base/memory/ptr_util.h" #include "base/test/scoped_feature_list.h" -#include "build/buildflag.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ui_base_features.h" -#include "ui/gtk/gtk_compat.h" -#include "ui/gtk/gtk_util.h" +#include "ui/gtk/gtk_ui_factory.h" #include "ui/native_theme/native_theme_color_id.h" #include "ui/native_theme/test/color_utils.h" +#include "ui/views/linux_ui/linux_ui.h" namespace gtk { @@ -25,11 +24,7 @@ class NativeThemeGtkRedirectedEquivalenceTest : public testing::TestWithParam< std::tuple<ui::NativeTheme::ColorScheme, ui::NativeTheme::ColorId>> { public: - NativeThemeGtkRedirectedEquivalenceTest() { - static bool loaded = LoadGtk(BUILDFLAG(GTK_VERSION)); - CHECK(loaded); - GtkInitFromCommandLine(base::CommandLine(base::CommandLine::NO_PROGRAM)); - } + NativeThemeGtkRedirectedEquivalenceTest() { gtk_ui_ = BuildGtkUi(); } static std::string ParamInfoToString( ::testing::TestParamInfo< @@ -43,6 +38,9 @@ class NativeThemeGtkRedirectedEquivalenceTest std::get<ui::NativeTheme::ColorId>(param_tuple)); } + protected: + views::LinuxUI* gtk_ui() { return gtk_ui_.get(); } + private: static std::string ColorSchemeToString(ui::NativeTheme::ColorScheme scheme) { switch (scheme) { @@ -58,6 +56,8 @@ class NativeThemeGtkRedirectedEquivalenceTest return "kPlatformHighContrast"; } } + + std::unique_ptr<views::LinuxUI> gtk_ui_; }; } // namespace @@ -68,7 +68,7 @@ TEST_P(NativeThemeGtkRedirectedEquivalenceTest, GetSystemColor) { auto color_id = std::get<ui::NativeTheme::ColorId>(param_tuple); // Verifies that colors with and without the Color Provider are the same. - auto* native_theme_gtk = NativeThemeGtk::instance(); + auto* native_theme_gtk = gtk_ui()->GetNativeTheme(nullptr); ui::test::PrintableSkColor original{ native_theme_gtk->GetSystemColor(color_id, color_scheme)}; diff --git a/chromium/ui/gtk/nav_button_provider_gtk.cc b/chromium/ui/gtk/nav_button_provider_gtk.cc index 085febcdeac..27239539af4 100644 --- a/chromium/ui/gtk/nav_button_provider_gtk.cc +++ b/chromium/ui/gtk/nav_button_provider_gtk.cc @@ -4,8 +4,6 @@ #include "ui/gtk/nav_button_provider_gtk.h" -#include <gtk/gtk.h> - #include "base/notreached.h" #include "ui/base/glib/glib_cast.h" #include "ui/base/glib/scoped_gobject.h" @@ -118,7 +116,7 @@ gfx::Size LoadNavButtonIcon( SkColor* pixels = reinterpret_cast<SkColor*>(g_malloc(nbytes)); size_t stride = sizeof(SkColor) * width; gdk_texture_download(texture, reinterpret_cast<guchar*>(pixels), stride); - SkColor fg = GetFgColorFromStyleContext(button_context); + SkColor fg = GtkStyleContextGetColor(button_context); for (int i = 0; i < width * height; ++i) pixels[i] = SkColorSetA(fg, SkColorGetA(pixels[i])); icon->texture = TakeGObject( @@ -278,8 +276,10 @@ class NavButtonImageSource : public gfx::ImageSkiaSource { } else { cairo_pattern_t* cr_pattern = nullptr; cairo_surface_t* cr_surface = nullptr; - GtkStyleContextGet(button_context, GTK_STYLE_PROPERTY_BACKGROUND_IMAGE, - &cr_pattern, nullptr); + GtkStyleContextGet( + button_context, + "background-image" /* GTK_STYLE_PROPERTY_BACKGROUND_IMAGE */, + &cr_pattern, nullptr); if (cr_pattern) { cairo_pattern_get_surface(cr_pattern, &cr_surface); if (cr_surface && diff --git a/chromium/ui/gtk/nav_button_provider_gtk.h b/chromium/ui/gtk/nav_button_provider_gtk.h index af521ea535d..ffedf019c8e 100644 --- a/chromium/ui/gtk/nav_button_provider_gtk.h +++ b/chromium/ui/gtk/nav_button_provider_gtk.h @@ -7,15 +7,13 @@ #include <map> -#include "base/component_export.h" #include "ui/gfx/image/image_skia.h" #include "ui/views/controls/button/button.h" #include "ui/views/linux_ui/nav_button_provider.h" namespace gtk { -class COMPONENT_EXPORT(GTK) NavButtonProviderGtk - : public views::NavButtonProvider { +class NavButtonProviderGtk : public views::NavButtonProvider { public: NavButtonProviderGtk(); ~NavButtonProviderGtk() override; diff --git a/chromium/ui/gtk/printing/print_dialog_gtk.cc b/chromium/ui/gtk/printing/print_dialog_gtk.cc index 7363dc20823..62108f0eb91 100644 --- a/chromium/ui/gtk/printing/print_dialog_gtk.cc +++ b/chromium/ui/gtk/printing/print_dialog_gtk.cc @@ -4,8 +4,6 @@ #include "ui/gtk/printing/print_dialog_gtk.h" -#include <gtk/gtkunixprint.h> - #include <algorithm> #include <cmath> #include <memory> @@ -28,13 +26,14 @@ #include "printing/print_job_constants.h" #include "printing/print_settings.h" #include "ui/aura/window.h" +#include "ui/gtk/gtk_compat.h" #include "ui/gtk/gtk_ui.h" -#include "ui/gtk/gtk_ui_delegate.h" +#include "ui/gtk/gtk_ui_platform.h" #include "ui/gtk/gtk_util.h" #include "ui/gtk/printing/printing_gtk_util.h" #if defined(USE_CUPS) -#include "printing/mojom/print.mojom.h" +#include "printing/mojom/print.mojom.h" // nogncheck #endif using printing::PageRanges; @@ -371,12 +370,12 @@ void PrintDialogGtk::ShowDialog( gtk::SetGtkTransientForAura(dialog_, parent_view); if (parent_view) parent_view->AddObserver(this); -#if BUILDFLAG(GTK_VERSION) >= 4 - gtk_window_set_hide_on_close(GTK_WINDOW(dialog_), true); -#else - g_signal_connect(dialog_, "delete-event", - G_CALLBACK(gtk_widget_hide_on_delete), nullptr); -#endif + if (gtk::GtkCheckVersion(4)) { + gtk_window_set_hide_on_close(GTK_WINDOW(dialog_), true); + } else { + g_signal_connect(dialog_, "delete-event", + G_CALLBACK(gtk_widget_hide_on_delete), nullptr); + } // Handle the case when the existing |gtk_settings_| has "selection" selected // as the page range, but |has_selection| is false. @@ -408,7 +407,7 @@ void PrintDialogGtk::ShowDialog( g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this); gtk_widget_show(dialog_); - gtk::GtkUi::GetDelegate()->ShowGtkWindow(GTK_WINDOW(dialog_)); + gtk::GtkUi::GetPlatform()->ShowGtkWindow(GTK_WINDOW(dialog_)); } void PrintDialogGtk::PrintDocument(const printing::MetafilePlayer& metafile, diff --git a/chromium/ui/gtk/printing/print_dialog_gtk.h b/chromium/ui/gtk/printing/print_dialog_gtk.h index 6eba9d4a192..bbdef2e00ce 100644 --- a/chromium/ui/gtk/printing/print_dialog_gtk.h +++ b/chromium/ui/gtk/printing/print_dialog_gtk.h @@ -5,8 +5,6 @@ #ifndef UI_GTK_PRINTING_PRINT_DIALOG_GTK_H_ #define UI_GTK_PRINTING_PRINT_DIALOG_GTK_H_ -#include <gtk/gtk.h> -#include <gtk/gtkunixprint.h> #include <memory> #include "base/compiler_specific.h" @@ -17,6 +15,7 @@ #include "printing/printing_context_linux.h" #include "ui/aura/window_observer.h" #include "ui/base/glib/glib_signal.h" +#include "ui/gtk/gtk_compat.h" namespace printing { class MetafilePlayer; diff --git a/chromium/ui/gtk/printing/printing_gtk_util.cc b/chromium/ui/gtk/printing/printing_gtk_util.cc index 0b7d8010cef..0ebed5603f8 100644 --- a/chromium/ui/gtk/printing/printing_gtk_util.cc +++ b/chromium/ui/gtk/printing/printing_gtk_util.cc @@ -4,9 +4,6 @@ #include "ui/gtk/printing/printing_gtk_util.h" -#include <gtk/gtk.h> -#include <gtk/gtkunixprint.h> - #include <string> #include "base/strings/utf_string_conversions.h" @@ -15,6 +12,7 @@ #include "printing/units.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size_f.h" +#include "ui/gtk/gtk_compat.h" namespace { diff --git a/chromium/ui/gtk/select_file_dialog_impl_gtk.cc b/chromium/ui/gtk/select_file_dialog_impl_gtk.cc index ead63d10c5d..d53f05761af 100644 --- a/chromium/ui/gtk/select_file_dialog_impl_gtk.cc +++ b/chromium/ui/gtk/select_file_dialog_impl_gtk.cc @@ -5,12 +5,11 @@ #include "ui/gtk/select_file_dialog_impl_gtk.h" #include <glib/gi18n.h> -#include <gtk/gtk.h> -#include <stddef.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> +#include <cstddef> #include <map> #include <memory> #include <set> @@ -30,7 +29,7 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/gtk/gtk_compat.h" #include "ui/gtk/gtk_ui.h" -#include "ui/gtk/gtk_ui_delegate.h" +#include "ui/gtk/gtk_ui_platform.h" #include "ui/gtk/gtk_util.h" #include "ui/gtk/select_file_dialog_impl.h" #include "ui/shell_dialogs/select_file_dialog.h" @@ -299,7 +298,7 @@ void SelectFileDialogImplGTK::SelectFileImpl( if (!GtkCheckVersion(4)) gtk_widget_show_all(dialog); - gtk::GtkUi::GetDelegate()->ShowGtkWindow(GTK_WINDOW(dialog)); + gtk::GtkUi::GetPlatform()->ShowGtkWindow(GTK_WINDOW(dialog)); } void SelectFileDialogImplGTK::AddFilters(GtkFileChooser* chooser) { @@ -395,9 +394,9 @@ GtkWidget* SelectFileDialogImplGTK::CreateFileOpenHelper( const std::string& title, const base::FilePath& default_path, gfx::NativeWindow parent) { - GtkWidget* dialog = gtk_file_chooser_dialog_new( + GtkWidget* dialog = GtkFileChooserDialogNew( title.c_str(), nullptr, GTK_FILE_CHOOSER_ACTION_OPEN, GetCancelLabel(), - GTK_RESPONSE_CANCEL, GetOpenLabel(), GTK_RESPONSE_ACCEPT, nullptr); + GTK_RESPONSE_CANCEL, GetOpenLabel(), GTK_RESPONSE_ACCEPT); SetGtkTransientForAura(dialog, parent); AddFilters(GTK_FILE_CHOOSER(dialog)); @@ -434,10 +433,10 @@ GtkWidget* SelectFileDialogImplGTK::CreateSelectFolderDialog( IDS_SELECT_UPLOAD_FOLDER_DIALOG_UPLOAD_BUTTON) : GetOpenLabel(); - GtkWidget* dialog = gtk_file_chooser_dialog_new( + GtkWidget* dialog = GtkFileChooserDialogNew( title_string.c_str(), nullptr, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GetCancelLabel(), GTK_RESPONSE_CANCEL, accept_button_label.c_str(), - GTK_RESPONSE_ACCEPT, nullptr); + GTK_RESPONSE_ACCEPT); SetGtkTransientForAura(dialog, parent); GtkFileChooser* chooser = GTK_FILE_CHOOSER(dialog); if (type == SELECT_UPLOAD_FOLDER || type == SELECT_EXISTING_FOLDER) @@ -498,10 +497,10 @@ GtkWidget* SelectFileDialogImplGTK::CreateSaveAsDialog( !title.empty() ? title : l10n_util::GetStringUTF8(IDS_SAVE_AS_DIALOG_TITLE); - GtkWidget* dialog = gtk_file_chooser_dialog_new( + GtkWidget* dialog = GtkFileChooserDialogNew( title_string.c_str(), nullptr, GTK_FILE_CHOOSER_ACTION_SAVE, GetCancelLabel(), GTK_RESPONSE_CANCEL, GetSaveLabel(), - GTK_RESPONSE_ACCEPT, nullptr); + GTK_RESPONSE_ACCEPT); SetGtkTransientForAura(dialog, parent); AddFilters(GTK_FILE_CHOOSER(dialog)); diff --git a/chromium/ui/gtk/settings_provider_gtk.cc b/chromium/ui/gtk/settings_provider_gtk.cc index 04a3c1e04d9..0163f4ece56 100644 --- a/chromium/ui/gtk/settings_provider_gtk.cc +++ b/chromium/ui/gtk/settings_provider_gtk.cc @@ -5,6 +5,8 @@ #include "ui/gtk/settings_provider_gtk.h" #include "base/strings/string_split.h" +#include "gtk_compat.h" +#include "ui/gtk/gtk_compat.h" #include "ui/gtk/gtk_ui.h" #include "ui/gtk/gtk_util.h" @@ -13,22 +15,18 @@ namespace gtk { namespace { std::string GetDecorationLayoutFromGtkWindow() { -#if BUILDFLAG(GTK_VERSION) >= 4 - NOTREACHED(); - static const char kDefaultGtkLayout[] = "menu:minimize,maximize,close"; - return kDefaultGtkLayout; -#else + DCHECK(!GtkCheckVersion(4)); + GtkCssContext context = GetStyleContextFromCss(""); gtk_style_context_add_class(context, "csd"); gchar* layout_c = nullptr; - gtk_style_context_get_style(context, "decoration-button-layout", &layout_c, - nullptr); + GtkStyleContextGetStyle(context, "decoration-button-layout", &layout_c, + nullptr); DCHECK(layout_c); std::string layout(layout_c); g_free(layout_c); return layout; -#endif } void ParseActionString(const std::string& value, diff --git a/chromium/ui/gtk/wayland/BUILD.gn b/chromium/ui/gtk/wayland/BUILD.gn deleted file mode 100644 index 599af208624..00000000000 --- a/chromium/ui/gtk/wayland/BUILD.gn +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/ozone.gni") - -assert(ozone_platform_wayland) - -component("wayland") { - output_name = "ui_gtk_wayland" - sources = [ - "gtk_ui_delegate_wayland_base.cc", - "gtk_ui_delegate_wayland_base.h", - ] - deps = [ - "//base", - "//build/config/linux/gtk", - ] - public_deps = [ "//ui/gtk:gtk_ui_delegate" ] - defines = [ "IS_GTK_WAYLAND_IMPL" ] -} diff --git a/chromium/ui/gtk/wayland/gtk_ui_delegate_wayland_base.cc b/chromium/ui/gtk/wayland/gtk_ui_delegate_wayland_base.cc deleted file mode 100644 index f075333af40..00000000000 --- a/chromium/ui/gtk/wayland/gtk_ui_delegate_wayland_base.cc +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/gtk/wayland/gtk_ui_delegate_wayland_base.h" - -#include <gtk/gtk.h> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/environment.h" -#include "base/logging.h" - -#if BUILDFLAG(GTK_VERSION) >= 4 -#include <gdk/wayland/gdkwayland.h> -#else -#include <gdk/gdkwayland.h> - -#define WEAK_GTK_FN(x) extern "C" __attribute__((weak)) decltype(x) x - -WEAK_GTK_FN(gdk_wayland_window_set_transient_for_exported); -#endif - -namespace ui { - -GtkUiDelegateWaylandBase::GtkUiDelegateWaylandBase() { - gdk_set_allowed_backends("wayland"); - // GDK_BACKEND takes precedence over gdk_set_allowed_backends(), so override - // it to ensure we get the wayland backend. - base::Environment::Create()->SetVar("GDK_BACKEND", "wayland"); -} - -GtkUiDelegateWaylandBase::~GtkUiDelegateWaylandBase() = default; - -void GtkUiDelegateWaylandBase::OnInitialized(GtkWidget* widget) { - // Nothing to do upon initialization for Wayland. -} - -GdkKeymap* GtkUiDelegateWaylandBase::GetGdkKeymap() { - NOTIMPLEMENTED_LOG_ONCE(); - return nullptr; -} - -GdkWindow* GtkUiDelegateWaylandBase::GetGdkWindow( - gfx::AcceleratedWidget window_id) { - NOTIMPLEMENTED_LOG_ONCE(); - return nullptr; -} - -bool GtkUiDelegateWaylandBase::SetGtkWidgetTransientFor( - GtkWidget* widget, - gfx::AcceleratedWidget parent) { -#if BUILDFLAG(GTK_VERSION) < 4 - if (!gdk_wayland_window_set_transient_for_exported) { - LOG(WARNING) << "set_transient_for_exported not supported in GTK version " - << GTK_MAJOR_VERSION << '.' << GTK_MINOR_VERSION << '.' - << GTK_MICRO_VERSION; - return false; - } -#endif - - return SetGtkWidgetTransientForImpl( - parent, base::BindOnce(&GtkUiDelegateWaylandBase::OnHandle, - weak_factory_.GetWeakPtr(), widget)); -} - -void GtkUiDelegateWaylandBase::ClearTransientFor( - gfx::AcceleratedWidget parent) { - // Nothing to do here. -} - -void GtkUiDelegateWaylandBase::ShowGtkWindow(GtkWindow* window) { - // TODO(crbug.com/1008755): Check if gtk_window_present_with_time is needed - // here as well, similarly to what is done in X11 impl. - gtk_window_present(window); -} - -void GtkUiDelegateWaylandBase::OnHandle(GtkWidget* widget, - const std::string& handle) { - char* parent = const_cast<char*>(handle.c_str()); -#if BUILDFLAG(GTK_VERSION) >= 4 - auto* toplevel = - GDK_TOPLEVEL(gtk_native_get_surface(gtk_widget_get_native(widget))); - gdk_wayland_toplevel_set_transient_for_exported(toplevel, parent); -#else - gdk_wayland_window_set_transient_for_exported(gtk_widget_get_window(widget), - parent); -#endif -} - -} // namespace ui diff --git a/chromium/ui/gtk/wayland/gtk_ui_platform_wayland.cc b/chromium/ui/gtk/wayland/gtk_ui_platform_wayland.cc new file mode 100644 index 00000000000..d7d503d8245 --- /dev/null +++ b/chromium/ui/gtk/wayland/gtk_ui_platform_wayland.cc @@ -0,0 +1,84 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gtk/wayland/gtk_ui_platform_wayland.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/environment.h" +#include "base/logging.h" +#include "ui/base/glib/glib_cast.h" +#include "ui/base/linux/linux_ui_delegate.h" +#include "ui/gtk/gtk_compat.h" + +namespace gtk { + +GtkUiPlatformWayland::GtkUiPlatformWayland() { + gdk_set_allowed_backends("wayland"); + // GDK_BACKEND takes precedence over gdk_set_allowed_backends(), so override + // it to ensure we get the wayland backend. + base::Environment::Create()->SetVar("GDK_BACKEND", "wayland"); +} + +GtkUiPlatformWayland::~GtkUiPlatformWayland() = default; + +void GtkUiPlatformWayland::OnInitialized(GtkWidget* widget) { + // Nothing to do upon initialization for Wayland. +} + +GdkKeymap* GtkUiPlatformWayland::GetGdkKeymap() { + NOTIMPLEMENTED_LOG_ONCE(); + return nullptr; +} + +GdkWindow* GtkUiPlatformWayland::GetGdkWindow( + gfx::AcceleratedWidget window_id) { + NOTIMPLEMENTED_LOG_ONCE(); + return nullptr; +} + +bool GtkUiPlatformWayland::SetGtkWidgetTransientFor( + GtkWidget* widget, + gfx::AcceleratedWidget parent) { + if (!gtk::GtkCheckVersion(3, 22)) { + LOG(WARNING) << "set_transient_for_exported not supported in GTK version " + << gtk_get_major_version() << '.' << gtk_get_minor_version() + << '.' << gtk_get_micro_version(); + return false; + } + + return ui::LinuxUiDelegate::GetInstance()->SetWidgetTransientFor( + parent, base::BindOnce(&GtkUiPlatformWayland::OnHandle, + weak_factory_.GetWeakPtr(), widget)); +} + +void GtkUiPlatformWayland::ClearTransientFor(gfx::AcceleratedWidget parent) { + // Nothing to do here. +} + +void GtkUiPlatformWayland::ShowGtkWindow(GtkWindow* window) { + // TODO(crbug.com/1008755): Check if gtk_window_present_with_time is needed + // here as well, similarly to what is done in X11 impl. + gtk_window_present(window); +} + +void GtkUiPlatformWayland::OnHandle(GtkWidget* widget, + const std::string& handle) { + char* parent = const_cast<char*>(handle.c_str()); + if (gtk::GtkCheckVersion(4)) { + auto* toplevel = GlibCast<GdkToplevel>( + gtk_native_get_surface(gtk_widget_get_native(widget)), + gdk_toplevel_get_type()); + gdk_wayland_toplevel_set_transient_for_exported(toplevel, parent); + } else { + gdk_wayland_window_set_transient_for_exported(gtk_widget_get_window(widget), + parent); + } +} + +int GtkUiPlatformWayland::GetGdkKeyState() { + return ui::LinuxUiDelegate::GetInstance()->GetKeyState(); +} + +} // namespace gtk diff --git a/chromium/ui/gtk/wayland/gtk_ui_delegate_wayland_base.h b/chromium/ui/gtk/wayland/gtk_ui_platform_wayland.h index afab8a113a6..41eae190208 100644 --- a/chromium/ui/gtk/wayland/gtk_ui_delegate_wayland_base.h +++ b/chromium/ui/gtk/wayland/gtk_ui_platform_wayland.h @@ -2,27 +2,25 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_GTK_WAYLAND_GTK_UI_DELEGATE_WAYLAND_BASE_H_ -#define UI_GTK_WAYLAND_GTK_UI_DELEGATE_WAYLAND_BASE_H_ +#ifndef UI_GTK_WAYLAND_GTK_UI_PLATFORM_WAYLAND_H_ +#define UI_GTK_WAYLAND_GTK_UI_PLATFORM_WAYLAND_H_ #include <string> #include "base/callback_forward.h" -#include "base/component_export.h" #include "base/memory/weak_ptr.h" -#include "ui/gtk/gtk_ui_delegate.h" +#include "ui/gtk/gtk_ui_platform.h" -namespace ui { +namespace gtk { -class COMPONENT_EXPORT(GTK_WAYLAND) GtkUiDelegateWaylandBase - : public GtkUiDelegate { +class GtkUiPlatformWayland : public GtkUiPlatform { public: - GtkUiDelegateWaylandBase(); - GtkUiDelegateWaylandBase(const GtkUiDelegateWaylandBase&) = delete; - GtkUiDelegateWaylandBase& operator=(const GtkUiDelegateWaylandBase&) = delete; - ~GtkUiDelegateWaylandBase() override; + GtkUiPlatformWayland(); + GtkUiPlatformWayland(const GtkUiPlatformWayland&) = delete; + GtkUiPlatformWayland& operator=(const GtkUiPlatformWayland&) = delete; + ~GtkUiPlatformWayland() override; - // GtkUiDelegate: + // GtkUiPlatform: void OnInitialized(GtkWidget* widget) override; GdkKeymap* GetGdkKeymap() override; GdkWindow* GetGdkWindow(gfx::AcceleratedWidget window_id) override; @@ -30,20 +28,16 @@ class COMPONENT_EXPORT(GTK_WAYLAND) GtkUiDelegateWaylandBase gfx::AcceleratedWidget parent) override; void ClearTransientFor(gfx::AcceleratedWidget parent) override; void ShowGtkWindow(GtkWindow* window) override; - - protected: - virtual bool SetGtkWidgetTransientForImpl( - gfx::AcceleratedWidget parent, - base::OnceCallback<void(const std::string&)> callback) = 0; + int GetGdkKeyState() override; private: // Called when xdg-foreign exports a parent window passed in // SetGtkWidgetTransientFor. void OnHandle(GtkWidget* widget, const std::string& handle); - base::WeakPtrFactory<GtkUiDelegateWaylandBase> weak_factory_{this}; + base::WeakPtrFactory<GtkUiPlatformWayland> weak_factory_{this}; }; -} // namespace ui +} // namespace gtk -#endif // UI_GTK_WAYLAND_GTK_UI_DELEGATE_WAYLAND_BASE_H_ +#endif // UI_GTK_WAYLAND_GTK_UI_PLATFORM_WAYLAND_H_ diff --git a/chromium/ui/gtk/x/BUILD.gn b/chromium/ui/gtk/x/BUILD.gn deleted file mode 100644 index 6046a39c7a1..00000000000 --- a/chromium/ui/gtk/x/BUILD.gn +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2020 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/ozone.gni") -import("//build/config/ui.gni") - -assert(use_x11 || ozone_platform_x11) - -component("x") { - output_name = "ui_gtk_x" - sources = [ - "gtk_event_loop_x11.cc", - "gtk_event_loop_x11.h", - "gtk_ui_delegate_x11.cc", - "gtk_ui_delegate_x11.h", - ] - deps = [ - "//base", - "//build/config/linux/gtk", - "//ui/base", - "//ui/events/platform/x11", - "//ui/gfx/x", - "//ui/platform_window/x11", - ] - public_deps = [ "//ui/gtk:gtk_ui_delegate" ] - defines = [ "IS_UI_GTK_X_IMPL" ] -} diff --git a/chromium/ui/gtk/x/gtk_event_loop_x11.cc b/chromium/ui/gtk/x/gtk_event_loop_x11.cc index 53007392631..942c76405cd 100644 --- a/chromium/ui/gtk/x/gtk_event_loop_x11.cc +++ b/chromium/ui/gtk/x/gtk_event_loop_x11.cc @@ -4,22 +4,14 @@ #include "ui/gtk/x/gtk_event_loop_x11.h" -#include <gtk/gtk.h> #include <xcb/xcb.h> #include <xcb/xproto.h> #include "ui/base/x/x11_util.h" #include "ui/gfx/x/event.h" +#include "ui/gtk/gtk_compat.h" -extern "C" { -#if BUILDFLAG(GTK_VERSION) >= 4 -unsigned long gdk_x11_surface_get_xid(GdkSurface* surface); -#else -unsigned long gdk_x11_window_get_xid(GdkWindow* window); -#endif -} - -namespace ui { +namespace gtk { namespace { @@ -29,7 +21,22 @@ x11::KeyButMask BuildXkbStateFromGdkEvent(unsigned int state, } x11::KeyEvent ConvertGdkEventToKeyEvent(GdkEvent* gdk_event) { -#if BUILDFLAG(GTK_VERSION) >= 4 + if (!gtk::GtkCheckVersion(4)) { + auto* key = reinterpret_cast<GdkEventKey*>(gdk_event); + DCHECK(key->type == GdkKeyPress() || key->type == GdkKeyRelease()); + return { + .opcode = key->type == GdkKeyPress() ? x11::KeyEvent::Press + : x11::KeyEvent::Release, + .send_event = key->send_event, + .detail = static_cast<x11::KeyCode>(key->hardware_keycode), + .time = static_cast<x11::Time>(key->time), + .root = ui::GetX11RootWindow(), + .event = static_cast<x11::Window>(gdk_x11_window_get_xid(key->window)), + .state = BuildXkbStateFromGdkEvent(key->state, key->group), + .same_screen = true, + }; + } + GdkKeymapKey* keys = nullptr; guint* keyvals = nullptr; gint n_entries = 0; @@ -50,11 +57,11 @@ x11::KeyEvent ConvertGdkEventToKeyEvent(GdkEvent* gdk_event) { } return { - .opcode = gdk_event_get_event_type(gdk_event) == GDK_KEY_PRESS + .opcode = gtk::GdkEventGetEventType(gdk_event) == GdkKeyPress() ? x11::KeyEvent::Press : x11::KeyEvent::Release, .detail = static_cast<x11::KeyCode>(keymap_key.keycode), - .time = static_cast<x11::Time>(gdk_event_get_time(gdk_event)), + .time = static_cast<x11::Time>(gtk::GdkEventGetTime(gdk_event)), .root = ui::GetX11RootWindow(), .event = static_cast<x11::Window>( gdk_x11_surface_get_xid(gdk_event_get_surface(gdk_event))), @@ -62,21 +69,6 @@ x11::KeyEvent ConvertGdkEventToKeyEvent(GdkEvent* gdk_event) { gdk_event_get_modifier_state(gdk_event), keymap_key.group), .same_screen = true, }; -#else - return { - .opcode = gdk_event->key.type == GDK_KEY_PRESS ? x11::KeyEvent::Press - : x11::KeyEvent::Release, - .send_event = gdk_event->key.send_event, - .detail = static_cast<x11::KeyCode>(gdk_event->key.hardware_keycode), - .time = static_cast<x11::Time>(gdk_event->key.time), - .root = ui::GetX11RootWindow(), - .event = static_cast<x11::Window>( - gdk_x11_window_get_xid(gdk_event->key.window)), - .state = - BuildXkbStateFromGdkEvent(gdk_event->key.state, gdk_event->key.group), - .same_screen = true, - }; -#endif } void ProcessGdkEvent(GdkEvent* gdk_event) { @@ -94,18 +86,11 @@ void ProcessGdkEvent(GdkEvent* gdk_event) { // corresponding key event in the X event queue. So we have to handle this // case. ibus-gtk is used through gtk-immodule to support IMEs. -#if BUILDFLAG(GTK_VERSION) >= 4 - auto event_type = gdk_event_get_event_type(gdk_event); -#else - auto event_type = gdk_event->type; -#endif - switch (event_type) { - case GDK_KEY_PRESS: - case GDK_KEY_RELEASE: - break; - default: - return; - } + auto event_type = gtk::GtkCheckVersion(4) + ? gtk::GdkEventGetEventType(gdk_event) + : *reinterpret_cast<GdkEventType*>(gdk_event); + if (event_type != GdkKeyPress() && event_type != GdkKeyRelease()) + return; // We want to process the gtk event; mapped to an X11 event immediately // otherwise if we put it back on the queue we may get items out of order. @@ -116,35 +101,35 @@ void ProcessGdkEvent(GdkEvent* gdk_event) { } // namespace GtkEventLoopX11::GtkEventLoopX11(GtkWidget* widget) { -#if BUILDFLAG(GTK_VERSION) >= 4 - surface_ = gtk_native_get_surface(gtk_widget_get_native(widget)); - signal_id_ = - g_signal_connect(surface_, "event", G_CALLBACK(OnEventThunk), this); -#else - gdk_event_handler_set(DispatchGdkEvent, nullptr, nullptr); -#endif + if (gtk::GtkCheckVersion(4)) { + surface_ = gtk_native_get_surface(gtk_widget_get_native(widget)); + signal_id_ = + g_signal_connect(surface_, "event", G_CALLBACK(OnEventThunk), this); + } else { + gdk_event_handler_set(DispatchGdkEvent, nullptr, nullptr); + } } GtkEventLoopX11::~GtkEventLoopX11() { -#if BUILDFLAG(GTK_VERSION) >= 4 - g_signal_handler_disconnect(surface_, signal_id_); -#else - gdk_event_handler_set(reinterpret_cast<GdkEventFunc>(gtk_main_do_event), - nullptr, nullptr); -#endif + if (gtk::GtkCheckVersion(4)) { + g_signal_handler_disconnect(surface_, signal_id_); + } else { + gdk_event_handler_set(reinterpret_cast<GdkEventFunc>(gtk_main_do_event), + nullptr, nullptr); + } } -#if BUILDFLAG(GTK_VERSION) >= 4 gboolean GtkEventLoopX11::OnEvent(GdkEvent* gdk_event) { + DCHECK(gtk::GtkCheckVersion(4)); ProcessGdkEvent(gdk_event); return false; } -#else + // static void GtkEventLoopX11::DispatchGdkEvent(GdkEvent* gdk_event, gpointer) { + DCHECK(!gtk::GtkCheckVersion(4)); ProcessGdkEvent(gdk_event); gtk_main_do_event(gdk_event); } -#endif -} // namespace ui +} // namespace gtk diff --git a/chromium/ui/gtk/x/gtk_event_loop_x11.h b/chromium/ui/gtk/x/gtk_event_loop_x11.h index 91cbe124268..a6e9251ea3e 100644 --- a/chromium/ui/gtk/x/gtk_event_loop_x11.h +++ b/chromium/ui/gtk/x/gtk_event_loop_x11.h @@ -5,14 +5,11 @@ #ifndef UI_GTK_X_GTK_EVENT_LOOP_X11_H_ #define UI_GTK_X_GTK_EVENT_LOOP_X11_H_ -#include <gdk/gdk.h> -#include <gtk/gtk.h> - #include "ui/base/glib/glib_integers.h" #include "ui/base/glib/glib_signal.h" -#include "ui/gtk/gtk_buildflags.h" +#include "ui/gtk/gtk_compat.h" -namespace ui { +namespace gtk { class GtkEventLoopX11 { public: @@ -23,15 +20,17 @@ class GtkEventLoopX11 { GtkEventLoopX11& operator=(const GtkEventLoopX11&) = delete; private: -#if BUILDFLAG(GTK_VERSION) >= 4 - CHROMEG_CALLBACK_0(GtkEventLoopX11, gboolean, OnEvent, GdkEvent*); + // This state is only used on GTK4. GdkSurface* surface_ = nullptr; gulong signal_id_ = 0; -#else + + // Only called on GTK3. static void DispatchGdkEvent(GdkEvent* gdk_event, gpointer); -#endif + + // Only called on GTK4. + CHROMEG_CALLBACK_0(GtkEventLoopX11, gboolean, OnEvent, GdkEvent*); }; -} // namespace ui +} // namespace gtk #endif // UI_GTK_X_GTK_EVENT_LOOP_X11_H_ diff --git a/chromium/ui/gtk/x/gtk_ui_delegate_x11.cc b/chromium/ui/gtk/x/gtk_ui_platform_x11.cc index 618d0865860..a61f472e7a8 100644 --- a/chromium/ui/gtk/x/gtk_ui_delegate_x11.cc +++ b/chromium/ui/gtk/x/gtk_ui_platform_x11.cc @@ -2,9 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/gtk/x/gtk_ui_delegate_x11.h" - -#include <gtk/gtk.h> +#include "ui/gtk/x/gtk_ui_platform_x11.h" #include "base/check.h" #include "base/environment.h" @@ -15,29 +13,14 @@ #include "ui/gfx/x/xlib_support.h" #include "ui/gfx/x/xproto.h" #include "ui/gfx/x/xproto_util.h" +#include "ui/gtk/gtk_compat.h" #include "ui/gtk/x/gtk_event_loop_x11.h" #include "ui/platform_window/x11/x11_window.h" #include "ui/platform_window/x11/x11_window_manager.h" -extern "C" { -GdkWindow* gdk_x11_window_foreign_new_for_display(GdkDisplay* display, - unsigned long window); - -GdkWindow* gdk_x11_window_lookup_for_display(GdkDisplay* display, - unsigned long window); - -#if BUILDFLAG(GTK_VERSION) >= 4 -unsigned long gdk_x11_surface_get_xid(GdkSurface* surface); -#else -unsigned long gdk_x11_window_get_xid(GdkWindow* window); -#endif -} - -namespace ui { +namespace gtk { -GtkUiDelegateX11::GtkUiDelegateX11(x11::Connection* connection) - : connection_(connection) { - DCHECK(connection_); +GtkUiPlatformX11::GtkUiPlatformX11() : connection_(x11::Connection::Get()) { gdk_set_allowed_backends("x11"); // GDK_BACKEND takes precedence over gdk_set_allowed_backends(), so override // it to ensure we get the x11 backend. @@ -45,9 +28,9 @@ GtkUiDelegateX11::GtkUiDelegateX11(x11::Connection* connection) x11::InitXlib(); } -GtkUiDelegateX11::~GtkUiDelegateX11() = default; +GtkUiPlatformX11::~GtkUiPlatformX11() = default; -void GtkUiDelegateX11::OnInitialized(GtkWidget* widget) { +void GtkUiPlatformX11::OnInitialized(GtkWidget* widget) { // Ensure the singleton instance of GtkEventLoopX11 is created and started. if (!event_loop_) event_loop_ = std::make_unique<GtkEventLoopX11>(widget); @@ -58,21 +41,13 @@ void GtkUiDelegateX11::OnInitialized(GtkWidget* widget) { x11::SetXlibErrorHandler(); } -GdkKeymap* GtkUiDelegateX11::GetGdkKeymap() { -#if BUILDFLAG(GTK_VERSION) >= 4 - NOTREACHED(); - return nullptr; -#else +GdkKeymap* GtkUiPlatformX11::GetGdkKeymap() { + DCHECK(!gtk::GtkCheckVersion(4)); return gdk_keymap_get_for_display(GetGdkDisplay()); -#endif } -GdkWindow* GtkUiDelegateX11::GetGdkWindow(gfx::AcceleratedWidget window_id) { -#if BUILDFLAG(GTK_VERSION) >= 4 - // This function is only used by InputMethodContextImplGtk with GTK3. - NOTREACHED(); - return nullptr; -#else +GdkWindow* GtkUiPlatformX11::GetGdkWindow(gfx::AcceleratedWidget window_id) { + DCHECK(!gtk::GtkCheckVersion(4)); GdkDisplay* display = GetGdkDisplay(); GdkWindow* gdk_window = gdk_x11_window_lookup_for_display( display, static_cast<uint32_t>(window_id)); @@ -82,18 +57,15 @@ GdkWindow* GtkUiDelegateX11::GetGdkWindow(gfx::AcceleratedWidget window_id) { gdk_window = gdk_x11_window_foreign_new_for_display( display, static_cast<uint32_t>(window_id)); return gdk_window; -#endif } -bool GtkUiDelegateX11::SetGtkWidgetTransientFor(GtkWidget* widget, +bool GtkUiPlatformX11::SetGtkWidgetTransientFor(GtkWidget* widget, gfx::AcceleratedWidget parent) { -#if BUILDFLAG(GTK_VERSION) >= 4 - auto x11_window = static_cast<x11::Window>(gdk_x11_surface_get_xid( - gtk_native_get_surface(gtk_widget_get_native(widget)))); -#else auto x11_window = static_cast<x11::Window>( - gdk_x11_window_get_xid(gtk_widget_get_window(widget))); -#endif + gtk::GtkCheckVersion(4) + ? gdk_x11_surface_get_xid( + gtk_native_get_surface(gtk_widget_get_native(widget))) + : gdk_x11_window_get_xid(gtk_widget_get_window(widget))); SetProperty(x11_window, x11::Atom::WM_TRANSIENT_FOR, x11::Atom::WINDOW, parent); SetProperty(x11_window, x11::GetAtom("_NET_WM_WINDOW_TYPE"), x11::Atom::ATOM, @@ -106,7 +78,7 @@ bool GtkUiDelegateX11::SetGtkWidgetTransientFor(GtkWidget* widget, return true; } -void GtkUiDelegateX11::ClearTransientFor(gfx::AcceleratedWidget parent) { +void GtkUiPlatformX11::ClearTransientFor(gfx::AcceleratedWidget parent) { ui::X11Window* parent_window = ui::X11WindowManager::GetInstance()->GetWindow(parent); // parent_window might be dead if there was a top-down window close @@ -114,24 +86,24 @@ void GtkUiDelegateX11::ClearTransientFor(gfx::AcceleratedWidget parent) { parent_window->SetTransientWindow(x11::Window::None); } -GdkDisplay* GtkUiDelegateX11::GetGdkDisplay() { +GdkDisplay* GtkUiPlatformX11::GetGdkDisplay() { if (!display_) display_ = gdk_display_get_default(); return display_; } -void GtkUiDelegateX11::ShowGtkWindow(GtkWindow* window) { +void GtkUiPlatformX11::ShowGtkWindow(GtkWindow* window) { // We need to call gtk_window_present after making the widgets visible to make // sure window gets correctly raised and gets focus. - DCHECK(X11EventSource::HasInstance()); + DCHECK(ui::X11EventSource::HasInstance()); gtk_window_present_with_time( window, - static_cast<uint32_t>(X11EventSource::GetInstance()->GetTimestamp())); + static_cast<uint32_t>(ui::X11EventSource::GetInstance()->GetTimestamp())); } -int GtkUiDelegateX11::GetGdkKeyState() { +int GtkUiPlatformX11::GetGdkKeyState() { auto* xevent = - X11EventSource::GetInstance()->connection()->dispatching_event(); + ui::X11EventSource::GetInstance()->connection()->dispatching_event(); if (!xevent) return ui::EF_NONE; @@ -141,4 +113,4 @@ int GtkUiDelegateX11::GetGdkKeyState() { return static_cast<int>(key_xevent->state); } -} // namespace ui +} // namespace gtk diff --git a/chromium/ui/gtk/x/gtk_ui_delegate_x11.h b/chromium/ui/gtk/x/gtk_ui_platform_x11.h index 334f79930c9..e96d888f766 100644 --- a/chromium/ui/gtk/x/gtk_ui_delegate_x11.h +++ b/chromium/ui/gtk/x/gtk_ui_platform_x11.h @@ -2,33 +2,28 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_GTK_X_GTK_UI_DELEGATE_X11_H_ -#define UI_GTK_X_GTK_UI_DELEGATE_X11_H_ +#ifndef UI_GTK_X_GTK_UI_PLATFORM_X11_H_ +#define UI_GTK_X_GTK_UI_PLATFORM_X11_H_ -#include "base/component_export.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/x/connection.h" -#include "ui/gtk/gtk_ui_delegate.h" +#include "ui/gtk/gtk_ui_platform.h" using GdkDisplay = struct _GdkDisplay; -namespace ui { +namespace gtk { class GtkEventLoopX11; -// GtkUiDelegate implementation for desktop Linux X11 backends. -// -// TODO(crbug.com/1002674): For now, this is used by both Aura (legacy) and -// Ozone X11. Move this into X11 Ozone backend once Linux Chrome migration to -// Ozone is completed. -class COMPONENT_EXPORT(UI_GTK_X) GtkUiDelegateX11 : public GtkUiDelegate { +// GtkUiPlatform implementation for desktop Linux X11 backends. +class GtkUiPlatformX11 : public GtkUiPlatform { public: - explicit GtkUiDelegateX11(x11::Connection* connection); - GtkUiDelegateX11(const GtkUiDelegateX11&) = delete; - GtkUiDelegateX11& operator=(const GtkUiDelegateX11&) = delete; - ~GtkUiDelegateX11() override; + GtkUiPlatformX11(); + GtkUiPlatformX11(const GtkUiPlatformX11&) = delete; + GtkUiPlatformX11& operator=(const GtkUiPlatformX11&) = delete; + ~GtkUiPlatformX11() override; - // GtkUiDelegate: + // GtkUiPlatform: void OnInitialized(GtkWidget* widget) override; GdkKeymap* GetGdkKeymap() override; GdkWindow* GetGdkWindow(gfx::AcceleratedWidget window_id) override; @@ -46,6 +41,6 @@ class COMPONENT_EXPORT(UI_GTK_X) GtkUiDelegateX11 : public GtkUiDelegate { std::unique_ptr<GtkEventLoopX11> event_loop_; }; -} // namespace ui +} // namespace gtk -#endif // UI_GTK_X_GTK_UI_DELEGATE_X11_H_ +#endif // UI_GTK_X_GTK_UI_PLATFORM_X11_H_ |