0

Remove GTK2 code

GTK2 code was historically kept around to keep the electron build working.  But
as of Nov 26, 2017, electron now uses GTK3 [1], so it should now be safe to
remove all of the old GTK2-only code.

[1] https://github.com/electron/electron/issues/2927#issuecomment-347092515

BUG=876558
R=sky

Change-Id: I78402053ae508ccd8fc7ac73697a861bb1ebacf6
Reviewed-on: https://chromium-review.googlesource.com/1183858
Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
Reviewed-by: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#585265}
This commit is contained in:
Tom Anderson
2018-08-22 21:52:02 +00:00
committed by Commit Bot
parent 16ac37826e
commit 287339e073
56 changed files with 444 additions and 1493 deletions

@@ -3,7 +3,6 @@
# found in the LICENSE file. # found in the LICENSE file.
import("//build/config/features.gni") import("//build/config/features.gni")
import("//build/config/linux/gtk/gtk.gni")
import("//build/config/linux/pkg_config.gni") import("//build/config/linux/pkg_config.gni")
import("//build/config/ui.gni") import("//build/config/ui.gni")
@@ -18,18 +17,20 @@ if (use_atk) {
} }
pkg_config("atk_base") { pkg_config("atk_base") {
packages = [ "atk" ] packages = [
"atk",
"atk-bridge-2.0",
]
atk_lib_dir = exec_script(pkg_config_script, atk_lib_dir = exec_script(pkg_config_script,
pkg_config_args + [ pkg_config_args + [
"--libdir", "--libdir",
"atk", "atk",
], ],
"string") "string")
defines = [ "ATK_LIB_DIR=\"$atk_lib_dir\"" ] defines = [
if (use_gtk3) { "ATK_LIB_DIR=\"$atk_lib_dir\"",
packages += [ "atk-bridge-2.0" ] "USE_ATK_BRIDGE",
defines += [ "USE_ATK_BRIDGE" ] ]
}
} }
# gn orders flags on a target before flags from configs. The default config # gn orders flags on a target before flags from configs. The default config

@@ -2,15 +2,22 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
import("//build/config/linux/gtk/gtk.gni")
import("//build/config/linux/pkg_config.gni") import("//build/config/linux/pkg_config.gni")
assert(is_linux, "This file should only be referenced on Linux") assert(is_linux, "This file should only be referenced on Linux")
# The target in this file will automatically reference GTK2 or GTK3 depending # GN doesn't check visibility for configs so we give this an obviously internal
# on the state of the build flag. Some builds reference both 2 and 3, and some # name to discourage random targets from accidentally depending on this and
# builds reference neither, so both need to be available but in different # bypassing the GTK target's visibility.
# directories so pkg-config is only run when necessary. pkg_config("gtk_internal_config") {
# Gtk requires gmodule, but it does not list it as a dependency in some
# misconfigured systems.
packages = [
"gmodule-2.0",
"gtk+-3.0",
"gthread-2.0",
]
}
# Basically no parts of Chrome should depend on GTK. To prevent accidents, the # Basically no parts of Chrome should depend on GTK. To prevent accidents, the
# parts that explicitly need GTK are whitelisted on this target. # parts that explicitly need GTK are whitelisted on this target.
@@ -27,15 +34,18 @@ group("gtk") {
"//remoting/host:remoting_me2me_host_static", "//remoting/host:remoting_me2me_host_static",
"//remoting/test:it2me_standalone_host_main", "//remoting/test:it2me_standalone_host_main",
"//webrtc/examples:peerconnection_client", "//webrtc/examples:peerconnection_client",
"//chrome/browser/ui/libgtkui:*",
] ]
if (use_gtk3) { public_configs = [ ":gtk_internal_config" ]
public_deps = [ }
"//build/config/linux/gtk3",
] # Depend on "gtkprint" to get this.
} else { pkg_config("gtkprint_internal_config") {
public_deps = [ packages = [ "gtk+-unix-print-3.0" ]
"//build/config/linux/gtk2", }
]
} group("gtkprint") {
visibility = [ "//chrome/browser/ui/libgtkui:*" ]
public_configs = [ ":gtkprint_internal_config" ]
} }

@@ -1,12 +0,0 @@
# Copyright 2016 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 this file if you need to know at build time whether we're compiling
# against GTK 2 or 3. But in most cases you can just depend on
# //build/config/linux/gtk and it will switch for you.
declare_args() {
# Whether to compile against GTKv3 instead of GTKv2.
use_gtk3 = true
}

@@ -1,43 +0,0 @@
# Copyright 2015 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/linux/pkg_config.gni")
assert(is_linux, "This file should only be referenced on Linux")
# Depend on //build/config/linux/gtk2 to use GTKv2. Depend on
# //build/config/linux/gtk to get GTK 2 or 3 depending on the build flags.
#
# GN doesn't check visibility for configs so we give this an obviously internal
# name to discourage random targets from accidentally depending on this and
# bypassing the GTK target's visibility.
pkg_config("gtk2_internal_config") {
# Gtk requires gmodule, but it does not list it as a dependency in some
# misconfigured systems.
packages = [
"gmodule-2.0",
"gtk+-2.0",
"gthread-2.0",
]
}
# Basically no parts of Chrome should depend on GTK. To prevent accidents, the
# parts that explicitly need GTK2 are whitelisted on this target.
group("gtk2") {
visibility = [
"//build/config/linux/gtk",
"//chrome/browser/ui/libgtkui:*",
]
public_configs = [ ":gtk2_internal_config" ]
}
# Depend on "gtkprint" to get this.
pkg_config("gtkprint2_internal_config") {
packages = [ "gtk+-unix-print-2.0" ]
}
group("gtkprint2") {
visibility = [ "//chrome/browser/ui/libgtkui:libgtk2ui" ]
public_configs = [ ":gtkprint2_internal_config" ]
}

@@ -1,43 +0,0 @@
# Copyright 2015 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/linux/pkg_config.gni")
assert(is_linux, "This file should only be referenced on Linux")
# Depend on //build/config/linux/gtk3 to use GTKv3. Depend on
# //build/config/linux/gtk to get GTK 2 or 3 depending on the build flags.
#
# GN doesn't check visibility for configs so we give this an obviously internal
# name to discourage random targets from accidentally depending on this and
# bypassing the GTK target's visibility.
pkg_config("gtk3_internal_config") {
# Gtk requires gmodule, but it does not list it as a dependency in some
# misconfigured systems.
packages = [
"gmodule-2.0",
"gtk+-3.0",
"gthread-2.0",
]
}
# Basically no parts of Chrome should depend on GTK. To prevent accidents, the
# parts that explicitly need GTK3 are whitelisted on this target.
group("gtk3") {
visibility = [
"//build/config/linux/gtk",
"//chrome/browser/ui/libgtkui:*",
]
public_configs = [ ":gtk3_internal_config" ]
}
# Depend on "gtkprint3" to get this.
pkg_config("gtkprint3_internal_config") {
packages = [ "gtk+-unix-print-3.0" ]
}
group("gtkprint3") {
visibility = [ "//chrome/browser/ui/libgtkui:libgtk3ui" ]
public_configs = [ ":gtkprint3_internal_config" ]
}

@@ -63,7 +63,6 @@ _packages_dev = (
'libglib2.0-dev', 'libglib2.0-dev',
'libglu1-mesa-dev', 'libglu1-mesa-dev',
'libgnome-keyring-dev', 'libgnome-keyring-dev',
'libgtk2.0-dev',
'libkrb5-dev', 'libkrb5-dev',
'libnspr4-dev', 'libnspr4-dev',
'libnss3-dev', 'libnss3-dev',
@@ -124,7 +123,6 @@ _packages_lib = (
'libfreetype6', 'libfreetype6',
'libglib2.0-0', 'libglib2.0-0',
'libgnome-keyring0', 'libgnome-keyring0',
'libgtk2.0-0',
'libpam0g', 'libpam0g',
'libpango1.0-0', 'libpango1.0-0',
'libpci3', 'libpci3',
@@ -160,7 +158,6 @@ _packages_dbg = (
'libcairo2-dbg', 'libcairo2-dbg',
'libfontconfig1-dbg', 'libfontconfig1-dbg',
'libglib2.0-0-dbg', 'libglib2.0-0-dbg',
'libgtk2.0-0-dbg',
'libpango1.0-0-dbg', 'libpango1.0-0-dbg',
'libpcre3-dbg', 'libpcre3-dbg',
'libpixman-1-0-dbg', 'libpixman-1-0-dbg',
@@ -220,7 +217,6 @@ _packages_nacl = (
'libgconf-2-4:i386', 'libgconf-2-4:i386',
'libglib2.0-0:i386', 'libglib2.0-0:i386',
'libgpm2:i386', 'libgpm2:i386',
'libgtk2.0-0:i386',
'libncurses5:i386', 'libncurses5:i386',
'libnss3:i386', 'libnss3:i386',
'libpango1.0-0:i386', 'libpango1.0-0:i386',

@@ -133,7 +133,6 @@ dev_list="\
git-core git-core
git-svn git-svn
gperf gperf
libappindicator-dev
libappindicator3-dev libappindicator3-dev
libasound2-dev libasound2-dev
libbrlapi-dev libbrlapi-dev
@@ -149,7 +148,6 @@ dev_list="\
libglib2.0-dev libglib2.0-dev
libglu1-mesa-dev libglu1-mesa-dev
libgnome-keyring-dev libgnome-keyring-dev
libgtk2.0-dev
libgtk-3-dev libgtk-3-dev
libkrb5-dev libkrb5-dev
libnspr4-dev libnspr4-dev
@@ -205,7 +203,6 @@ chromeos_lib_list="libpulse0 libbz2-1.0"
# List of required run-time libraries # List of required run-time libraries
common_lib_list="\ common_lib_list="\
libappindicator1
libappindicator3-1 libappindicator3-1
libasound2 libasound2
libatk1.0-0 libatk1.0-0
@@ -219,7 +216,6 @@ common_lib_list="\
libfreetype6 libfreetype6
libglib2.0-0 libglib2.0-0
libgnome-keyring0 libgnome-keyring0
libgtk2.0-0
libgtk-3-0 libgtk-3-0
libpam0g libpam0g
libpango1.0-0 libpango1.0-0
@@ -275,6 +271,8 @@ backwards_compatible_list="\
language-pack-fr language-pack-fr
language-pack-he language-pack-he
language-pack-zh-hant language-pack-zh-hant
libappindicator-dev
libappindicator1
libappindicator3-1:i386 libappindicator3-1:i386
libdconf-dev libdconf-dev
libdconf-dev:i386 libdconf-dev:i386
@@ -289,6 +287,9 @@ backwards_compatible_list="\
libgl1-mesa-dev libgl1-mesa-dev
libgl1-mesa-glx:i386 libgl1-mesa-glx:i386
libgles2-mesa-dev libgles2-mesa-dev
libgtk2.0-0
libgtk2.0-0:i386
libgtk2.0-dev
mesa-common-dev mesa-common-dev
msttcorefonts msttcorefonts
ttf-dejavu-core ttf-dejavu-core
@@ -385,7 +386,6 @@ nacl_list="\
libfontconfig1:i386 libfontconfig1:i386
libglib2.0-0:i386 libglib2.0-0:i386
libgpm2:i386 libgpm2:i386
libgtk2.0-0:i386
libgtk-3-0:i386 libgtk-3-0:i386
libncurses5:i386 libncurses5:i386
lib32ncurses5-dev lib32ncurses5-dev

@@ -137,7 +137,6 @@ DEBIAN_PACKAGES="\
libgtk-3-0 libgtk-3-0
libgtk-3-dev libgtk-3-dev
libgtk2.0-0 libgtk2.0-0
libgtk2.0-dev
libharfbuzz-dev libharfbuzz-dev
libharfbuzz-gobject0 libharfbuzz-gobject0
libharfbuzz-icu0 libharfbuzz-icu0

@@ -17,7 +17,7 @@ IconLoader::IconGroup IconLoader::GroupForFilepath(
// static // static
scoped_refptr<base::TaskRunner> IconLoader::GetReadIconTaskRunner() { scoped_refptr<base::TaskRunner> IconLoader::GetReadIconTaskRunner() {
// ReadIcon() calls into views::LinuxUI and GTK2 code, so it must be on the UI // ReadIcon() calls into views::LinuxUI and GTK code, so it must be on the UI
// thread. // thread.
return content::BrowserThread::GetTaskRunnerForThread( return content::BrowserThread::GetTaskRunnerForThread(
content::BrowserThread::UI); content::BrowserThread::UI);

@@ -5,158 +5,121 @@
assert(is_linux, "This file should only be referenced on Linux") assert(is_linux, "This file should only be referenced on Linux")
import("//build/config/features.gni") import("//build/config/features.gni")
import("//build/config/linux/gtk/gtk.gni")
import("//printing/buildflags/buildflags.gni") import("//printing/buildflags/buildflags.gni")
# Automatically depends on the GTK version associated with the current build component("libgtkui") {
# flags. sources = [
group("libgtkui") { "app_indicator_icon.cc",
if (use_gtk3) { "app_indicator_icon.h",
public_deps = [ "app_indicator_icon_menu.cc",
":libgtk3ui", "app_indicator_icon_menu.h",
] "chrome_gtk_frame.cc",
} else { "chrome_gtk_frame.h",
public_deps = [ "chrome_gtk_menu_subclasses.cc",
":libgtk2ui", "chrome_gtk_menu_subclasses.h",
] "gtk_background_painter.cc",
} "gtk_background_painter.h",
} "gtk_event_loop.cc",
"gtk_event_loop.h",
template("libgtkui") { "gtk_key_bindings_handler.cc",
component(target_name) { "gtk_key_bindings_handler.h",
sources = invoker.sources + [ "gtk_signal.h",
"app_indicator_icon.cc", "gtk_status_icon.cc",
"app_indicator_icon.h", "gtk_status_icon.h",
"app_indicator_icon_menu.cc", "gtk_ui.cc",
"app_indicator_icon_menu.h", "gtk_ui.h",
"chrome_gtk_frame.cc", "gtk_util.cc",
"chrome_gtk_frame.h", "gtk_util.h",
"chrome_gtk_menu_subclasses.cc", "libgtkui_export.h",
"chrome_gtk_menu_subclasses.h", "menu_util.cc",
"gtk_event_loop.cc", "menu_util.h",
"gtk_event_loop.h", "native_theme_gtk.cc",
"gtk_key_bindings_handler.cc", "native_theme_gtk.h",
"gtk_key_bindings_handler.h", "nav_button_provider_gtk.cc",
"gtk_signal.h", "nav_button_provider_gtk.h",
"gtk_status_icon.cc", "print_dialog_gtk.cc",
"gtk_status_icon.h", "print_dialog_gtk.h",
"gtk_ui.cc", "printing_gtk_util.cc",
"gtk_ui.h", "printing_gtk_util.h",
"gtk_util.cc", "select_file_dialog_impl.cc",
"gtk_util.h", "select_file_dialog_impl.h",
"libgtkui_export.h", "select_file_dialog_impl_gtk.cc",
"menu_util.cc", "select_file_dialog_impl_gtk.h",
"menu_util.h", "select_file_dialog_impl_kde.cc",
"settings_provider.h", "settings_provider.h",
"print_dialog_gtk.cc", "settings_provider_gtk.cc",
"print_dialog_gtk.h", "settings_provider_gtk.h",
"printing_gtk_util.cc", "skia_utils_gtk.cc",
"printing_gtk_util.h", "skia_utils_gtk.h",
"select_file_dialog_impl.cc", "unity_service.cc",
"select_file_dialog_impl.h", "unity_service.h",
"select_file_dialog_impl_gtk.cc", "x11_input_method_context_impl_gtk.cc",
"select_file_dialog_impl_gtk.h", "x11_input_method_context_impl_gtk.h",
"select_file_dialog_impl_kde.cc", ]
"skia_utils_gtk.cc",
"skia_utils_gtk.h", configs += [
"unity_service.cc", "//build/config/linux/pangocairo",
"unity_service.h", "//build/config/linux:x11",
"x11_input_method_context_impl_gtk.cc", ]
"x11_input_method_context_impl_gtk.h",
] if (use_gio) {
sources += [
configs += [ "settings_provider_gsettings.cc",
"//build/config/linux/pangocairo", "settings_provider_gsettings.h",
"//build/config/linux:x11",
]
if (use_gio) {
sources += [
"settings_provider_gsettings.cc",
"settings_provider_gsettings.h",
]
configs += [ "//build/linux:gio_config" ]
}
if (use_cups) {
configs += [ "//printing:cups" ]
}
defines = [ "LIBGTKUI_IMPLEMENTATION" ]
deps = invoker.deps + [
"//chrome/browser/ui/views",
"//chrome/common:constants",
"//base",
"//base:i18n",
"//base/third_party/dynamic_annotations",
"//cc/paint",
"//chrome/common:buildflags",
"//chrome:extra_resources",
"//chrome:resources",
"//chrome:strings",
"//chrome/app:command_ids",
"//chrome/app/theme:theme_resources",
"//components/prefs",
"//components/resources",
"//content/public/browser",
"//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.
"//third_party:freetype_harfbuzz",
"//ui/aura",
"//ui/base",
"//ui/base/ime",
"//ui/display",
"//ui/events",
"//ui/events:dom_keyboard_layout",
"//ui/events:dom_keycode_converter",
"//ui/events:events_base",
"//ui/events/platform/x11",
"//ui/gfx",
"//ui/gfx/geometry",
"//ui/gfx/x",
"//ui/native_theme",
"//ui/resources",
"//ui/shell_dialogs",
"//ui/strings",
"//ui/views",
]
public_deps = [
"//chrome/browser:theme_properties",
]
}
}
if (use_gtk3) {
libgtkui("libgtk3ui") {
sources = [
"gtk3_background_painter.cc",
"gtk3_background_painter.h",
"native_theme_gtk3.cc",
"native_theme_gtk3.h",
"nav_button_provider_gtk3.cc",
"nav_button_provider_gtk3.h",
"settings_provider_gtk3.cc",
"settings_provider_gtk3.h",
]
deps = [
"//build/config/linux/gtk3",
"//build/config/linux/gtk3:gtkprint3",
]
}
} else {
libgtkui("libgtk2ui") {
sources = [
"native_theme_gtk2.cc",
"native_theme_gtk2.h",
]
deps = [
"//build/config/linux/gtk2",
"//build/config/linux/gtk2:gtkprint2",
] ]
configs += [ "//build/linux:gio_config" ]
} }
if (use_cups) {
configs += [ "//printing:cups" ]
}
defines = [ "LIBGTKUI_IMPLEMENTATION" ]
deps = [
"//base",
"//base:i18n",
"//base/third_party/dynamic_annotations",
"//build/config/linux/gtk",
"//build/config/linux/gtk:gtkprint",
"//cc/paint",
"//chrome:extra_resources",
"//chrome:resources",
"//chrome:strings",
"//chrome/app:command_ids",
"//chrome/app/theme:theme_resources",
"//chrome/browser/ui/views",
"//chrome/common:buildflags",
"//chrome/common:constants",
"//components/prefs",
"//components/resources",
"//content/public/browser",
"//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.
"//third_party:freetype_harfbuzz",
"//ui/aura",
"//ui/base",
"//ui/base/ime",
"//ui/display",
"//ui/events",
"//ui/events:dom_keyboard_layout",
"//ui/events:dom_keycode_converter",
"//ui/events:events_base",
"//ui/events/platform/x11",
"//ui/gfx",
"//ui/gfx/geometry",
"//ui/gfx/x",
"//ui/native_theme",
"//ui/resources",
"//ui/shell_dialogs",
"//ui/strings",
"//ui/views",
]
public_deps = [
"//chrome/browser:theme_properties",
]
} }

@@ -12,6 +12,7 @@
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/md5.h" #include "base/md5.h"
#include "base/memory/ref_counted_memory.h" #include "base/memory/ref_counted_memory.h"
#include "base/strings/stringize_macros.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
@@ -90,27 +91,15 @@ void EnsureMethodsLoaded() {
void* indicator_lib = nullptr; void* indicator_lib = nullptr;
// These include guards might be unnecessary, but let's keep them as a if (!indicator_lib) {
// precaution since using gtk2 and gtk3 symbols in the same process is indicator_lib =
// explicitly unsupported. dlopen("libappindicator" STRINGIZE(GTK_MAJOR_VERSION) ".so", RTLD_LAZY);
#if GTK_MAJOR_VERSION == 2 }
if (!indicator_lib)
indicator_lib = dlopen("libappindicator.so", RTLD_LAZY);
if (!indicator_lib) if (!indicator_lib) {
indicator_lib = dlopen("libappindicator.so.1", RTLD_LAZY); indicator_lib = dlopen(
"libappindicator" STRINGIZE(GTK_MAJOR_VERSION) ".so.1", RTLD_LAZY);
if (!indicator_lib) }
indicator_lib = dlopen("libappindicator.so.0", RTLD_LAZY);
#endif
#if GTK_MAJOR_VERSION == 3
if (!indicator_lib)
indicator_lib = dlopen("libappindicator3.so", RTLD_LAZY);
if (!indicator_lib)
indicator_lib = dlopen("libappindicator3.so.1", RTLD_LAZY);
#endif
if (!indicator_lib) if (!indicator_lib)
return; return;

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/ui/libgtkui/gtk3_background_painter.h" #include "chrome/browser/ui/libgtkui/gtk_background_painter.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
#include "ui/views/controls/button/button.h" #include "ui/views/controls/button/button.h"
@@ -32,14 +32,13 @@ GtkStateFlags ButtonStateToStateFlags(views::Button::ButtonState state) {
} // namespace } // namespace
Gtk3BackgroundPainter::Gtk3BackgroundPainter(const views::Button* button, GtkBackgroundPainter::GtkBackgroundPainter(const views::Button* button,
ScopedStyleContext context) ScopedStyleContext context)
: button_(button), context_(std::move(context)) {} : button_(button), context_(std::move(context)) {}
Gtk3BackgroundPainter::~Gtk3BackgroundPainter() {} GtkBackgroundPainter::~GtkBackgroundPainter() {}
void Gtk3BackgroundPainter::Paint(gfx::Canvas* canvas, void GtkBackgroundPainter::Paint(gfx::Canvas* canvas, views::View* view) const {
views::View* view) const {
float scale = canvas->image_scale(); float scale = canvas->image_scale();
SkBitmap bitmap; SkBitmap bitmap;
bitmap.allocN32Pixels(scale * view->width(), scale * view->height()); bitmap.allocN32Pixels(scale * view->width(), scale * view->height());
@@ -53,7 +52,7 @@ void Gtk3BackgroundPainter::Paint(gfx::Canvas* canvas,
canvas->DrawImageInt(gfx::ImageSkia(gfx::ImageSkiaRep(bitmap, scale)), 0, 0); canvas->DrawImageInt(gfx::ImageSkia(gfx::ImageSkiaRep(bitmap, scale)), 0, 0);
} }
GtkStateFlags Gtk3BackgroundPainter::CalculateStateFlags() const { GtkStateFlags GtkBackgroundPainter::CalculateStateFlags() const {
GtkStateFlags state = ButtonStateToStateFlags(button_->state()); GtkStateFlags state = ButtonStateToStateFlags(button_->state());
if (!button_->GetWidget()->IsActive()) if (!button_->GetWidget()->IsActive())
state = static_cast<GtkStateFlags>(state | GTK_STATE_FLAG_BACKDROP); state = static_cast<GtkStateFlags>(state | GTK_STATE_FLAG_BACKDROP);

@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_LIBGTKUI_GTK3_BACKGROUND_PAINTER_H_ #ifndef CHROME_BROWSER_UI_LIBGTKUI_GTK_BACKGROUND_PAINTER_H_
#define CHROME_BROWSER_UI_LIBGTKUI_GTK3_BACKGROUND_PAINTER_H_ #define CHROME_BROWSER_UI_LIBGTKUI_GTK_BACKGROUND_PAINTER_H_
#include "base/macros.h" #include "base/macros.h"
#include "chrome/browser/ui/libgtkui/gtk_util.h" #include "chrome/browser/ui/libgtkui/gtk_util.h"
@@ -18,11 +18,10 @@ namespace libgtkui {
// A background that paints a button using GTK foreign drawing. The // A background that paints a button using GTK foreign drawing. The
// type and style of widget to be drawn is decided by a // type and style of widget to be drawn is decided by a
// GtkStyleContext. Always renders a background and a frame. // GtkStyleContext. Always renders a background and a frame.
class Gtk3BackgroundPainter : public views::Background { class GtkBackgroundPainter : public views::Background {
public: public:
Gtk3BackgroundPainter(const views::Button* button, GtkBackgroundPainter(const views::Button* button, ScopedStyleContext context);
ScopedStyleContext context); ~GtkBackgroundPainter() override;
~Gtk3BackgroundPainter() override;
void Paint(gfx::Canvas* canvas, views::View* view) const override; void Paint(gfx::Canvas* canvas, views::View* view) const override;
@@ -32,9 +31,9 @@ class Gtk3BackgroundPainter : public views::Background {
const views::Button* button_; const views::Button* button_;
mutable ScopedStyleContext context_; mutable ScopedStyleContext context_;
DISALLOW_COPY_AND_ASSIGN(Gtk3BackgroundPainter); DISALLOW_COPY_AND_ASSIGN(GtkBackgroundPainter);
}; };
} // namespace libgtkui } // namespace libgtkui
#endif // CHROME_BROWSER_UI_LIBGTKUI_GTK3_BACKGROUND_PAINTER_H_ #endif // CHROME_BROWSER_UI_LIBGTKUI_GTK_BACKGROUND_PAINTER_H_

@@ -17,21 +17,21 @@
namespace libgtkui { namespace libgtkui {
// static // static
Gtk2EventLoop* Gtk2EventLoop::GetInstance() { GtkEventLoop* GtkEventLoop::GetInstance() {
return base::Singleton<Gtk2EventLoop>::get(); return base::Singleton<GtkEventLoop>::get();
} }
Gtk2EventLoop::Gtk2EventLoop() { GtkEventLoop::GtkEventLoop() {
gdk_event_handler_set(DispatchGdkEvent, nullptr, nullptr); gdk_event_handler_set(DispatchGdkEvent, nullptr, nullptr);
} }
Gtk2EventLoop::~Gtk2EventLoop() { GtkEventLoop::~GtkEventLoop() {
gdk_event_handler_set(reinterpret_cast<GdkEventFunc>(gtk_main_do_event), gdk_event_handler_set(reinterpret_cast<GdkEventFunc>(gtk_main_do_event),
nullptr, nullptr); nullptr, nullptr);
} }
// static // static
void Gtk2EventLoop::DispatchGdkEvent(GdkEvent* gdk_event, gpointer) { void GtkEventLoop::DispatchGdkEvent(GdkEvent* gdk_event, gpointer) {
switch (gdk_event->type) { switch (gdk_event->type) {
case GDK_KEY_PRESS: case GDK_KEY_PRESS:
case GDK_KEY_RELEASE: case GDK_KEY_RELEASE:
@@ -45,7 +45,7 @@ void Gtk2EventLoop::DispatchGdkEvent(GdkEvent* gdk_event, gpointer) {
} }
// static // static
void Gtk2EventLoop::ProcessGdkEventKey(const GdkEventKey& gdk_event_key) { void GtkEventLoop::ProcessGdkEventKey(const GdkEventKey& gdk_event_key) {
// This function translates GdkEventKeys into XKeyEvents and puts them to // This function translates GdkEventKeys into XKeyEvents and puts them to
// the X event queue. // the X event queue.
// //
@@ -72,7 +72,7 @@ void Gtk2EventLoop::ProcessGdkEventKey(const GdkEventKey& gdk_event_key) {
x_event.xkey.keycode = gdk_event_key.hardware_keycode; x_event.xkey.keycode = gdk_event_key.hardware_keycode;
x_event.xkey.same_screen = true; x_event.xkey.same_screen = true;
// We want to process the gtk2 event; mapped to an X11 event immediately // 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. // otherwise if we put it back on the queue we may get items out of order.
if (ui::X11EventSource* x11_source = ui::X11EventSource::GetInstance()) if (ui::X11EventSource* x11_source = ui::X11EventSource::GetInstance())
x11_source->DispatchXEventNow(&x_event); x11_source->DispatchXEventNow(&x_event);

@@ -18,20 +18,20 @@ struct DefaultSingletonTraits;
namespace libgtkui { namespace libgtkui {
class Gtk2EventLoop { class GtkEventLoop {
public: public:
static Gtk2EventLoop* GetInstance(); static GtkEventLoop* GetInstance();
private: private:
friend struct base::DefaultSingletonTraits<Gtk2EventLoop>; friend struct base::DefaultSingletonTraits<GtkEventLoop>;
Gtk2EventLoop(); GtkEventLoop();
~Gtk2EventLoop(); ~GtkEventLoop();
static void DispatchGdkEvent(GdkEvent* gdk_event, gpointer); static void DispatchGdkEvent(GdkEvent* gdk_event, gpointer);
static void ProcessGdkEventKey(const GdkEventKey& gdk_event_key); static void ProcessGdkEventKey(const GdkEventKey& gdk_event_key);
DISALLOW_COPY_AND_ASSIGN(Gtk2EventLoop); DISALLOW_COPY_AND_ASSIGN(GtkEventLoop);
}; };
} // namespace libgtkui } // namespace libgtkui

@@ -30,7 +30,7 @@ using ui::TextEditCommand;
namespace libgtkui { namespace libgtkui {
Gtk2KeyBindingsHandler::Gtk2KeyBindingsHandler() GtkKeyBindingsHandler::GtkKeyBindingsHandler()
: fake_window_(gtk_offscreen_window_new()), : fake_window_(gtk_offscreen_window_new()),
handler_(CreateNewHandler()), handler_(CreateNewHandler()),
has_xkb_(false) { has_xkb_(false) {
@@ -43,12 +43,12 @@ Gtk2KeyBindingsHandler::Gtk2KeyBindingsHandler()
&major, &minor); &major, &minor);
} }
Gtk2KeyBindingsHandler::~Gtk2KeyBindingsHandler() { GtkKeyBindingsHandler::~GtkKeyBindingsHandler() {
gtk_widget_destroy(handler_); gtk_widget_destroy(handler_);
gtk_widget_destroy(fake_window_); gtk_widget_destroy(fake_window_);
} }
bool Gtk2KeyBindingsHandler::MatchEvent( bool GtkKeyBindingsHandler::MatchEvent(
const ui::Event& event, const ui::Event& event,
std::vector<ui::TextEditCommandAuraLinux>* edit_commands) { std::vector<ui::TextEditCommandAuraLinux>* edit_commands) {
CHECK(event.IsKeyEvent()); CHECK(event.IsKeyEvent());
@@ -78,7 +78,7 @@ bool Gtk2KeyBindingsHandler::MatchEvent(
return matched; return matched;
} }
GtkWidget* Gtk2KeyBindingsHandler::CreateNewHandler() { GtkWidget* GtkKeyBindingsHandler::CreateNewHandler() {
Handler* handler = Handler* handler =
static_cast<Handler*>(g_object_new(HandlerGetType(), nullptr)); static_cast<Handler*>(g_object_new(HandlerGetType(), nullptr));
@@ -96,12 +96,12 @@ GtkWidget* Gtk2KeyBindingsHandler::CreateNewHandler() {
return GTK_WIDGET(handler); return GTK_WIDGET(handler);
} }
void Gtk2KeyBindingsHandler::EditCommandMatched(TextEditCommand command, void GtkKeyBindingsHandler::EditCommandMatched(TextEditCommand command,
const std::string& value) { const std::string& value) {
edit_commands_.push_back(ui::TextEditCommandAuraLinux(command, value)); edit_commands_.push_back(ui::TextEditCommandAuraLinux(command, value));
} }
void Gtk2KeyBindingsHandler::BuildGdkEventKeyFromXEvent( void GtkKeyBindingsHandler::BuildGdkEventKeyFromXEvent(
const ui::PlatformEvent& xevent, const ui::PlatformEvent& xevent,
GdkEventKey* gdk_event) { GdkEventKey* gdk_event) {
GdkKeymap* keymap = gdk_keymap_get_for_display(gdk_display_get_default()); GdkKeymap* keymap = gdk_keymap_get_for_display(gdk_display_get_default());
@@ -139,11 +139,11 @@ void Gtk2KeyBindingsHandler::BuildGdkEventKeyFromXEvent(
gdk_event->state |= state; gdk_event->state |= state;
} }
void Gtk2KeyBindingsHandler::HandlerInit(Handler* self) { void GtkKeyBindingsHandler::HandlerInit(Handler* self) {
self->owner = nullptr; self->owner = nullptr;
} }
void Gtk2KeyBindingsHandler::HandlerClassInit(HandlerClass* klass) { void GtkKeyBindingsHandler::HandlerClassInit(HandlerClass* klass) {
GtkTextViewClass* text_view_class = GTK_TEXT_VIEW_CLASS(klass); GtkTextViewClass* text_view_class = GTK_TEXT_VIEW_CLASS(klass);
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass); GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
@@ -177,11 +177,11 @@ void Gtk2KeyBindingsHandler::HandlerClassInit(HandlerClass* klass) {
G_CALLBACK(ToggleCursorVisible)); G_CALLBACK(ToggleCursorVisible));
} }
GType Gtk2KeyBindingsHandler::HandlerGetType() { GType GtkKeyBindingsHandler::HandlerGetType() {
static volatile gsize type_id_volatile = 0; static volatile gsize type_id_volatile = 0;
if (g_once_init_enter(&type_id_volatile)) { if (g_once_init_enter(&type_id_volatile)) {
GType type_id = g_type_register_static_simple( GType type_id = g_type_register_static_simple(
GTK_TYPE_TEXT_VIEW, g_intern_static_string("Gtk2KeyBindingsHandler"), GTK_TYPE_TEXT_VIEW, g_intern_static_string("GtkKeyBindingsHandler"),
sizeof(HandlerClass), sizeof(HandlerClass),
reinterpret_cast<GClassInitFunc>(HandlerClassInit), sizeof(Handler), reinterpret_cast<GClassInitFunc>(HandlerClassInit), sizeof(Handler),
reinterpret_cast<GInstanceInitFunc>(HandlerInit), reinterpret_cast<GInstanceInitFunc>(HandlerInit),
@@ -191,7 +191,7 @@ GType Gtk2KeyBindingsHandler::HandlerGetType() {
return type_id_volatile; return type_id_volatile;
} }
Gtk2KeyBindingsHandler* Gtk2KeyBindingsHandler::GetHandlerOwner( GtkKeyBindingsHandler* GtkKeyBindingsHandler::GetHandlerOwner(
GtkTextView* text_view) { GtkTextView* text_view) {
Handler* handler = Handler* handler =
G_TYPE_CHECK_INSTANCE_CAST(text_view, HandlerGetType(), Handler); G_TYPE_CHECK_INSTANCE_CAST(text_view, HandlerGetType(), Handler);
@@ -199,24 +199,24 @@ Gtk2KeyBindingsHandler* Gtk2KeyBindingsHandler::GetHandlerOwner(
return handler->owner; return handler->owner;
} }
void Gtk2KeyBindingsHandler::BackSpace(GtkTextView* text_view) { void GtkKeyBindingsHandler::BackSpace(GtkTextView* text_view) {
GetHandlerOwner(text_view)->EditCommandMatched( GetHandlerOwner(text_view)->EditCommandMatched(
TextEditCommand::DELETE_BACKWARD, std::string()); TextEditCommand::DELETE_BACKWARD, std::string());
} }
void Gtk2KeyBindingsHandler::CopyClipboard(GtkTextView* text_view) { void GtkKeyBindingsHandler::CopyClipboard(GtkTextView* text_view) {
GetHandlerOwner(text_view)->EditCommandMatched(TextEditCommand::COPY, GetHandlerOwner(text_view)->EditCommandMatched(TextEditCommand::COPY,
std::string()); std::string());
} }
void Gtk2KeyBindingsHandler::CutClipboard(GtkTextView* text_view) { void GtkKeyBindingsHandler::CutClipboard(GtkTextView* text_view) {
GetHandlerOwner(text_view)->EditCommandMatched(TextEditCommand::CUT, GetHandlerOwner(text_view)->EditCommandMatched(TextEditCommand::CUT,
std::string()); std::string());
} }
void Gtk2KeyBindingsHandler::DeleteFromCursor(GtkTextView* text_view, void GtkKeyBindingsHandler::DeleteFromCursor(GtkTextView* text_view,
GtkDeleteType type, GtkDeleteType type,
gint count) { gint count) {
if (!count) if (!count)
return; return;
@@ -263,7 +263,7 @@ void Gtk2KeyBindingsHandler::DeleteFromCursor(GtkTextView* text_view,
return; return;
} }
Gtk2KeyBindingsHandler* owner = GetHandlerOwner(text_view); GtkKeyBindingsHandler* owner = GetHandlerOwner(text_view);
if (count < 0) if (count < 0)
count = -count; count = -count;
for (; count > 0; --count) { for (; count > 0; --count) {
@@ -273,18 +273,18 @@ void Gtk2KeyBindingsHandler::DeleteFromCursor(GtkTextView* text_view,
} }
} }
void Gtk2KeyBindingsHandler::InsertAtCursor(GtkTextView* text_view, void GtkKeyBindingsHandler::InsertAtCursor(GtkTextView* text_view,
const gchar* str) { const gchar* str) {
if (str && *str) { if (str && *str) {
GetHandlerOwner(text_view)->EditCommandMatched(TextEditCommand::INSERT_TEXT, GetHandlerOwner(text_view)->EditCommandMatched(TextEditCommand::INSERT_TEXT,
str); str);
} }
} }
void Gtk2KeyBindingsHandler::MoveCursor(GtkTextView* text_view, void GtkKeyBindingsHandler::MoveCursor(GtkTextView* text_view,
GtkMovementStep step, GtkMovementStep step,
gint count, gint count,
gboolean extend_selection) { gboolean extend_selection) {
if (!count) if (!count)
return; return;
@@ -381,52 +381,51 @@ void Gtk2KeyBindingsHandler::MoveCursor(GtkTextView* text_view,
return; return;
} }
Gtk2KeyBindingsHandler* owner = GetHandlerOwner(text_view); GtkKeyBindingsHandler* owner = GetHandlerOwner(text_view);
if (count < 0) if (count < 0)
count = -count; count = -count;
for (; count > 0; --count) for (; count > 0; --count)
owner->EditCommandMatched(command, std::string()); owner->EditCommandMatched(command, std::string());
} }
void Gtk2KeyBindingsHandler::MoveViewport(GtkTextView* text_view, void GtkKeyBindingsHandler::MoveViewport(GtkTextView* text_view,
GtkScrollStep step, GtkScrollStep step,
gint count) { gint count) {
// Not supported by webkit. // Not supported by webkit.
} }
void Gtk2KeyBindingsHandler::PasteClipboard(GtkTextView* text_view) { void GtkKeyBindingsHandler::PasteClipboard(GtkTextView* text_view) {
GetHandlerOwner(text_view)->EditCommandMatched(TextEditCommand::PASTE, GetHandlerOwner(text_view)->EditCommandMatched(TextEditCommand::PASTE,
std::string()); std::string());
} }
void Gtk2KeyBindingsHandler::SelectAll(GtkTextView* text_view, void GtkKeyBindingsHandler::SelectAll(GtkTextView* text_view, gboolean select) {
gboolean select) {
GetHandlerOwner(text_view)->EditCommandMatched( GetHandlerOwner(text_view)->EditCommandMatched(
select ? TextEditCommand::SELECT_ALL : TextEditCommand::UNSELECT, select ? TextEditCommand::SELECT_ALL : TextEditCommand::UNSELECT,
std::string()); std::string());
} }
void Gtk2KeyBindingsHandler::SetAnchor(GtkTextView* text_view) { void GtkKeyBindingsHandler::SetAnchor(GtkTextView* text_view) {
GetHandlerOwner(text_view)->EditCommandMatched(TextEditCommand::SET_MARK, GetHandlerOwner(text_view)->EditCommandMatched(TextEditCommand::SET_MARK,
std::string()); std::string());
} }
void Gtk2KeyBindingsHandler::ToggleCursorVisible(GtkTextView* text_view) { void GtkKeyBindingsHandler::ToggleCursorVisible(GtkTextView* text_view) {
// Not supported by webkit. // Not supported by webkit.
} }
void Gtk2KeyBindingsHandler::ToggleOverwrite(GtkTextView* text_view) { void GtkKeyBindingsHandler::ToggleOverwrite(GtkTextView* text_view) {
// Not supported by webkit. // Not supported by webkit.
} }
gboolean Gtk2KeyBindingsHandler::ShowHelp(GtkWidget* widget, gboolean GtkKeyBindingsHandler::ShowHelp(GtkWidget* widget,
GtkWidgetHelpType arg1) { GtkWidgetHelpType arg1) {
// Just for disabling the default handler. // Just for disabling the default handler.
return FALSE; return FALSE;
} }
void Gtk2KeyBindingsHandler::MoveFocus(GtkWidget* widget, void GtkKeyBindingsHandler::MoveFocus(GtkWidget* widget,
GtkDirectionType arg1) { GtkDirectionType arg1) {
// Just for disabling the default handler. // Just for disabling the default handler.
} }

@@ -38,10 +38,10 @@ namespace libgtkui {
// definition of webkit edit commands. // definition of webkit edit commands.
// See webkit/glue/editor_client_impl.cc for key bindings predefined in our // See webkit/glue/editor_client_impl.cc for key bindings predefined in our
// webkit glue. // webkit glue.
class Gtk2KeyBindingsHandler { class GtkKeyBindingsHandler {
public: public:
Gtk2KeyBindingsHandler(); GtkKeyBindingsHandler();
virtual ~Gtk2KeyBindingsHandler(); virtual ~GtkKeyBindingsHandler();
// Matches a key event against predefined gtk key bindings, false will be // Matches a key event against predefined gtk key bindings, false will be
// returned if the key event doesn't correspond to a predefined key binding. // returned if the key event doesn't correspond to a predefined key binding.
@@ -54,7 +54,7 @@ class Gtk2KeyBindingsHandler {
// Object structure of Handler class, which is derived from GtkTextView. // Object structure of Handler class, which is derived from GtkTextView.
struct Handler { struct Handler {
GtkTextView parent_object; GtkTextView parent_object;
Gtk2KeyBindingsHandler* owner; GtkKeyBindingsHandler* owner;
}; };
// Class structure of Handler class. // Class structure of Handler class.
@@ -82,8 +82,8 @@ class Gtk2KeyBindingsHandler {
// Registeres Handler class to GObject type system and return its type id. // Registeres Handler class to GObject type system and return its type id.
static GType HandlerGetType(); static GType HandlerGetType();
// Gets the Gtk2KeyBindingsHandler object which owns the Handler object. // Gets the GtkKeyBindingsHandler object which owns the Handler object.
static Gtk2KeyBindingsHandler* GetHandlerOwner(GtkTextView* text_view); static GtkKeyBindingsHandler* GetHandlerOwner(GtkTextView* text_view);
// Handler of "backspace" signal. // Handler of "backspace" signal.
static void BackSpace(GtkTextView* text_view); static void BackSpace(GtkTextView* text_view);

@@ -17,17 +17,15 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
namespace libgtkui { namespace libgtkui {
Gtk2StatusIcon::Gtk2StatusIcon(const gfx::ImageSkia& image, GtkStatusIcon::GtkStatusIcon(const gfx::ImageSkia& image,
const base::string16& tool_tip) { const base::string16& tool_tip) {
GdkPixbuf* pixbuf = GdkPixbufFromSkBitmap(*image.bitmap()); GdkPixbuf* pixbuf = GdkPixbufFromSkBitmap(*image.bitmap());
{ {
#if GTK_MAJOR_VERSION == 3 // GTK has a bug that leaks 384 bytes when creating a GtkStatusIcon. It
// Gtk3 has a bug that leaks 384 bytes when creating a // will not be fixed since the status icon was deprecated in version 3.14.
// GtkStatusIcon. It will not be fixed since the status icon was // Luckily, Chromium doesn't need to create a status icon very often, if at
// deprectaed in version 3.14. Luckily, Chromium doesn't need to // all.
// create a status icon very often, if at all.
ANNOTATE_SCOPED_MEMORY_LEAK; ANNOTATE_SCOPED_MEMORY_LEAK;
#endif
gtk_status_icon_ = gtk_status_icon_new_from_pixbuf(pixbuf); gtk_status_icon_ = gtk_status_icon_new_from_pixbuf(pixbuf);
} }
g_object_unref(pixbuf); g_object_unref(pixbuf);
@@ -39,41 +37,41 @@ Gtk2StatusIcon::Gtk2StatusIcon(const gfx::ImageSkia& image,
SetToolTip(tool_tip); SetToolTip(tool_tip);
} }
Gtk2StatusIcon::~Gtk2StatusIcon() { GtkStatusIcon::~GtkStatusIcon() {
gtk_status_icon_set_visible(gtk_status_icon_, FALSE); gtk_status_icon_set_visible(gtk_status_icon_, FALSE);
g_object_unref(gtk_status_icon_); g_object_unref(gtk_status_icon_);
} }
void Gtk2StatusIcon::SetImage(const gfx::ImageSkia& image) { void GtkStatusIcon::SetImage(const gfx::ImageSkia& image) {
GdkPixbuf* pixbuf = GdkPixbufFromSkBitmap(*image.bitmap()); GdkPixbuf* pixbuf = GdkPixbufFromSkBitmap(*image.bitmap());
gtk_status_icon_set_from_pixbuf(gtk_status_icon_, pixbuf); gtk_status_icon_set_from_pixbuf(gtk_status_icon_, pixbuf);
g_object_unref(pixbuf); g_object_unref(pixbuf);
} }
void Gtk2StatusIcon::SetToolTip(const base::string16& tool_tip) { void GtkStatusIcon::SetToolTip(const base::string16& tool_tip) {
gtk_status_icon_set_tooltip_text(gtk_status_icon_, gtk_status_icon_set_tooltip_text(gtk_status_icon_,
base::UTF16ToUTF8(tool_tip).c_str()); base::UTF16ToUTF8(tool_tip).c_str());
} }
void Gtk2StatusIcon::UpdatePlatformContextMenu(ui::MenuModel* model) { void GtkStatusIcon::UpdatePlatformContextMenu(ui::MenuModel* model) {
menu_.reset(); menu_.reset();
if (model) if (model)
menu_.reset(new AppIndicatorIconMenu(model)); menu_.reset(new AppIndicatorIconMenu(model));
} }
void Gtk2StatusIcon::RefreshPlatformContextMenu() { void GtkStatusIcon::RefreshPlatformContextMenu() {
if (menu_.get()) if (menu_.get())
menu_->Refresh(); menu_->Refresh();
} }
void Gtk2StatusIcon::OnClick(GtkStatusIcon* status_icon) { void GtkStatusIcon::OnClick(GtkStatusIcon* status_icon) {
if (delegate()) if (delegate())
delegate()->OnClick(); delegate()->OnClick();
} }
void Gtk2StatusIcon::OnContextMenuRequested(GtkStatusIcon* status_icon, void GtkStatusIcon::OnContextMenuRequested(GtkStatusIcon* status_icon,
guint button, guint button,
guint32 activate_time) { guint32 activate_time) {
if (menu_.get()) { if (menu_.get()) {
gtk_menu_popup(menu_->GetGtkMenu(), nullptr, nullptr, gtk_menu_popup(menu_->GetGtkMenu(), nullptr, nullptr,
gtk_status_icon_position_menu, gtk_status_icon_, button, gtk_status_icon_position_menu, gtk_status_icon_, button,

@@ -29,10 +29,10 @@ class AppIndicatorIconMenu;
// Status icon implementation which uses the system tray X11 spec (via // Status icon implementation which uses the system tray X11 spec (via
// GtkStatusIcon). // GtkStatusIcon).
class Gtk2StatusIcon : public views::StatusIconLinux { class GtkStatusIcon : public views::StatusIconLinux {
public: public:
Gtk2StatusIcon(const gfx::ImageSkia& image, const base::string16& tool_tip); GtkStatusIcon(const gfx::ImageSkia& image, const base::string16& tool_tip);
~Gtk2StatusIcon() override; ~GtkStatusIcon() override;
// Overridden from views::StatusIconLinux: // Overridden from views::StatusIconLinux:
void SetImage(const gfx::ImageSkia& image) override; void SetImage(const gfx::ImageSkia& image) override;
@@ -41,20 +41,20 @@ class Gtk2StatusIcon : public views::StatusIconLinux {
void RefreshPlatformContextMenu() override; void RefreshPlatformContextMenu() override;
private: private:
CHROMEG_CALLBACK_0(Gtk2StatusIcon, void, OnClick, GtkStatusIcon*); CHROMEG_CALLBACK_0(GtkStatusIcon, void, OnClick, GtkStatusIcon*);
CHROMEG_CALLBACK_2(Gtk2StatusIcon, CHROMEG_CALLBACK_2(GtkStatusIcon,
void, void,
OnContextMenuRequested, OnContextMenuRequested,
GtkStatusIcon*, GtkStatusIcon*,
guint, guint,
guint); guint);
GtkStatusIcon* gtk_status_icon_; ::GtkStatusIcon* gtk_status_icon_;
std::unique_ptr<AppIndicatorIconMenu> menu_; std::unique_ptr<AppIndicatorIconMenu> menu_;
DISALLOW_COPY_AND_ASSIGN(Gtk2StatusIcon); DISALLOW_COPY_AND_ASSIGN(GtkStatusIcon);
}; };
} // namespace libgtkui } // namespace libgtkui

@@ -35,9 +35,12 @@
#include "chrome/browser/ui/libgtkui/gtk_key_bindings_handler.h" #include "chrome/browser/ui/libgtkui/gtk_key_bindings_handler.h"
#include "chrome/browser/ui/libgtkui/gtk_status_icon.h" #include "chrome/browser/ui/libgtkui/gtk_status_icon.h"
#include "chrome/browser/ui/libgtkui/gtk_util.h" #include "chrome/browser/ui/libgtkui/gtk_util.h"
#include "chrome/browser/ui/libgtkui/native_theme_gtk.h"
#include "chrome/browser/ui/libgtkui/nav_button_provider_gtk.h"
#include "chrome/browser/ui/libgtkui/print_dialog_gtk.h" #include "chrome/browser/ui/libgtkui/print_dialog_gtk.h"
#include "chrome/browser/ui/libgtkui/printing_gtk_util.h" #include "chrome/browser/ui/libgtkui/printing_gtk_util.h"
#include "chrome/browser/ui/libgtkui/select_file_dialog_impl.h" #include "chrome/browser/ui/libgtkui/select_file_dialog_impl.h"
#include "chrome/browser/ui/libgtkui/settings_provider_gtk.h"
#include "chrome/browser/ui/libgtkui/skia_utils_gtk.h" #include "chrome/browser/ui/libgtkui/skia_utils_gtk.h"
#include "chrome/browser/ui/libgtkui/unity_service.h" #include "chrome/browser/ui/libgtkui/unity_service.h"
#include "chrome/browser/ui/libgtkui/x11_input_method_context_impl_gtk.h" #include "chrome/browser/ui/libgtkui/x11_input_method_context_impl_gtk.h"
@@ -73,14 +76,6 @@
#include "ui/views/linux_ui/window_button_order_observer.h" #include "ui/views/linux_ui/window_button_order_observer.h"
#include "ui/views/resources/grit/views_resources.h" #include "ui/views/resources/grit/views_resources.h"
#if GTK_MAJOR_VERSION == 2
#include "chrome/browser/ui/libgtkui/native_theme_gtk2.h" // nogncheck
#elif GTK_MAJOR_VERSION == 3
#include "chrome/browser/ui/libgtkui/native_theme_gtk3.h" // nogncheck
#include "chrome/browser/ui/libgtkui/nav_button_provider_gtk3.h" // nogncheck
#include "chrome/browser/ui/libgtkui/settings_provider_gtk3.h" // nogncheck
#endif
#if defined(USE_GIO) #if defined(USE_GIO)
#include "chrome/browser/ui/libgtkui/settings_provider_gsettings.h" #include "chrome/browser/ui/libgtkui/settings_provider_gsettings.h"
#endif #endif
@@ -140,49 +135,6 @@ class GtkButtonImageSource : public gfx::ImageSkiaSource {
width, height, width * 4); width, height, width * 4);
cairo_t* cr = cairo_create(surface); cairo_t* cr = cairo_create(surface);
#if GTK_MAJOR_VERSION == 2
// Create a temporary GTK button to snapshot
GtkWidget* window = gtk_offscreen_window_new();
GtkWidget* button = gtk_toggle_button_new();
if (state_ == ui::NativeTheme::kPressed)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), true);
else if (state_ == ui::NativeTheme::kDisabled)
gtk_widget_set_sensitive(button, false);
gtk_widget_set_size_request(button, width, height);
gtk_container_add(GTK_CONTAINER(window), button);
if (is_blue_)
TurnButtonBlue(button);
gtk_widget_show_all(window);
if (focus_)
GTK_WIDGET_SET_FLAGS(button, GTK_HAS_FOCUS);
int w, h;
GdkPixmap* pixmap;
{
// http://crbug.com/346740
ANNOTATE_SCOPED_MEMORY_LEAK;
pixmap = gtk_widget_get_snapshot(button, nullptr);
}
gdk_drawable_get_size(GDK_DRAWABLE(pixmap), &w, &h);
GdkColormap* colormap = gdk_drawable_get_colormap(pixmap);
GdkPixbuf* pixbuf = gdk_pixbuf_get_from_drawable(
nullptr, GDK_DRAWABLE(pixmap), colormap, 0, 0, 0, 0, w, h);
gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
cairo_paint(cr);
g_object_unref(pixbuf);
g_object_unref(pixmap);
gtk_widget_destroy(window);
#else
ScopedStyleContext context = GetStyleContextFromCss( ScopedStyleContext context = GetStyleContextFromCss(
is_blue_ ? "GtkButton#button.default.suggested-action" is_blue_ ? "GtkButton#button.default.suggested-action"
: "GtkButton#button"); : "GtkButton#button");
@@ -224,7 +176,6 @@ class GtkButtonImageSource : public gfx::ImageSkiaSource {
gtk_render_focus(context, cr, focus_rect.x(), focus_rect.y(), gtk_render_focus(context, cr, focus_rect.x(), focus_rect.y(),
focus_rect.width(), focus_rect.height()); focus_rect.width(), focus_rect.height());
} }
#endif
cairo_destroy(cr); cairo_destroy(cr);
cairo_surface_destroy(surface); cairo_surface_destroy(surface);
@@ -283,11 +234,15 @@ int indicators_count;
// The unknown content type. // The unknown content type.
const char* kUnknownContentType = "application/octet-stream"; const char* kUnknownContentType = "application/octet-stream";
using GdkSetAllowedBackendsFn = void (*)(const gchar*);
// Place this function pointer in read-only memory after being resolved to
// prevent it being tampered with. See https://crbug.com/771365 for details.
PROTECTED_MEMORY_SECTION base::ProtectedMemory<GdkSetAllowedBackendsFn>
g_gdk_set_allowed_backends;
std::unique_ptr<SettingsProvider> CreateSettingsProvider(GtkUi* gtk_ui) { std::unique_ptr<SettingsProvider> CreateSettingsProvider(GtkUi* gtk_ui) {
#if GTK_MAJOR_VERSION == 3
if (GtkVersionCheck(3, 14)) if (GtkVersionCheck(3, 14))
return std::make_unique<SettingsProviderGtk3>(gtk_ui); return std::make_unique<SettingsProviderGtk>(gtk_ui);
#endif
#if defined(USE_GIO) #if defined(USE_GIO)
return std::make_unique<SettingsProviderGSettings>(gtk_ui); return std::make_unique<SettingsProviderGSettings>(gtk_ui);
#else #else
@@ -345,10 +300,8 @@ gfx::FontRenderParams GetGtkFontRenderParams() {
} }
views::LinuxUI::NonClientWindowFrameAction GetDefaultMiddleClickAction() { views::LinuxUI::NonClientWindowFrameAction GetDefaultMiddleClickAction() {
#if GTK_MAJOR_VERSION == 3
if (GtkVersionCheck(3, 14)) if (GtkVersionCheck(3, 14))
return views::LinuxUI::WINDOW_FRAME_ACTION_NONE; return views::LinuxUI::WINDOW_FRAME_ACTION_NONE;
#endif
std::unique_ptr<base::Environment> env(base::Environment::Create()); std::unique_ptr<base::Environment> env(base::Environment::Create());
switch (base::nix::GetDesktopEnvironment(env.get())) { switch (base::nix::GetDesktopEnvironment(env.get())) {
case base::nix::DESKTOP_ENVIRONMENT_KDE4: case base::nix::DESKTOP_ENVIRONMENT_KDE4:
@@ -363,13 +316,6 @@ views::LinuxUI::NonClientWindowFrameAction GetDefaultMiddleClickAction() {
} }
} }
#if GTK_MAJOR_VERSION > 2
using GdkSetAllowedBackendsFn = void (*)(const gchar*);
// Place this function pointer in read-only memory after being resolved to
// prevent it being tampered with. See https://crbug.com/771365 for details.
PROTECTED_MEMORY_SECTION base::ProtectedMemory<GdkSetAllowedBackendsFn>
g_gdk_set_allowed_backends;
// COLOR_TOOLBAR_TOP_SEPARATOR represents the border between tabs and the // COLOR_TOOLBAR_TOP_SEPARATOR represents the border between tabs and the
// frame, as well as the border between tabs and the toolbar. For this // frame, as well as the border between tabs and the toolbar. For this
// reason, it is difficult to calculate the One True Color that works well on // reason, it is difficult to calculate the One True Color that works well on
@@ -420,7 +366,6 @@ SkColor GetToolbarTopSeparatorColor(SkColor header_fg,
border.l = l; border.l = l;
return HSLToSkColor(border, a * 0xff); return HSLToSkColor(border, a * 0xff);
} }
#endif
} // namespace } // namespace
@@ -431,7 +376,6 @@ GtkUi::GtkUi() {
GetDefaultMiddleClickAction(); GetDefaultMiddleClickAction();
window_frame_actions_[WINDOW_FRAME_ACTION_SOURCE_RIGHT_CLICK] = window_frame_actions_[WINDOW_FRAME_ACTION_SOURCE_RIGHT_CLICK] =
views::LinuxUI::WINDOW_FRAME_ACTION_MENU; views::LinuxUI::WINDOW_FRAME_ACTION_MENU;
#if GTK_MAJOR_VERSION > 2
// Force Gtk to use Xwayland if it would have used wayland. libgtkui assumes // Force Gtk to use Xwayland if it would have used wayland. libgtkui assumes
// the use of X11 (eg. X11InputMethodContextImplGtk) and will crash under // the use of X11 (eg. X11InputMethodContextImplGtk) and will crash under
// other backends. // other backends.
@@ -444,23 +388,13 @@ GtkUi::GtkUi() {
DCHECK(*g_gdk_set_allowed_backends); DCHECK(*g_gdk_set_allowed_backends);
if (*g_gdk_set_allowed_backends) if (*g_gdk_set_allowed_backends)
base::UnsanitizedCfiCall(g_gdk_set_allowed_backends)("x11"); base::UnsanitizedCfiCall(g_gdk_set_allowed_backends)("x11");
#endif
#if GTK_MAJOR_VERSION >= 3
// Avoid GTK initializing atk-bridge, and let AuraLinux implementation // Avoid GTK initializing atk-bridge, and let AuraLinux implementation
// do it once it is ready. // do it once it is ready.
std::unique_ptr<base::Environment> env(base::Environment::Create()); std::unique_ptr<base::Environment> env(base::Environment::Create());
env->SetVar("NO_AT_BRIDGE", "1"); env->SetVar("NO_AT_BRIDGE", "1");
#endif
GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess());
#if GTK_MAJOR_VERSION == 2 native_theme_ = NativeThemeGtk::instance();
native_theme_ = NativeThemeGtk2::instance();
fake_window_ = chrome_gtk_frame_new();
#elif GTK_MAJOR_VERSION == 3
native_theme_ = NativeThemeGtk3::instance();
fake_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL); fake_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);
#else
#error "Unsupported GTK version"
#endif
gtk_widget_realize(fake_window_); gtk_widget_realize(fake_window_);
} }
@@ -494,7 +428,7 @@ void GtkUi::Initialize() {
#if BUILDFLAG(ENABLE_PRINTING) #if BUILDFLAG(ENABLE_PRINTING)
printing::PrintingContextLinux::SetCreatePrintDialogFunction( printing::PrintingContextLinux::SetCreatePrintDialogFunction(
&PrintDialogGtk2::CreatePrintDialog); &PrintDialogGtk::CreatePrintDialog);
printing::PrintingContextLinux::SetPdfPaperSizeFunction( printing::PrintingContextLinux::SetPdfPaperSizeFunction(
&GetPdfPaperSizeDeviceUnitsGtk); &GetPdfPaperSizeDeviceUnitsGtk);
#endif #endif
@@ -504,8 +438,8 @@ void GtkUi::Initialize() {
indicators_count = 0; indicators_count = 0;
// Instantiate the singleton instance of Gtk2EventLoop. // Instantiate the singleton instance of GtkEventLoop.
Gtk2EventLoop::GetInstance(); GtkEventLoop::GetInstance();
} }
bool GtkUi::GetTint(int id, color_utils::HSL* tint) const { bool GtkUi::GetTint(int id, color_utils::HSL* tint) const {
@@ -653,7 +587,7 @@ std::unique_ptr<views::StatusIconLinux> GtkUi::CreateLinuxStatusIcon(
image, tool_tip)); image, tool_tip));
} else { } else {
return std::unique_ptr<views::StatusIconLinux>( return std::unique_ptr<views::StatusIconLinux>(
new Gtk2StatusIcon(image, tool_tip)); new GtkStatusIcon(image, tool_tip));
} }
} }
@@ -788,7 +722,7 @@ std::unique_ptr<ui::LinuxInputMethodContext> GtkUi::CreateInputMethodContext(
ui::LinuxInputMethodContextDelegate* delegate, ui::LinuxInputMethodContextDelegate* delegate,
bool is_simple) const { bool is_simple) const {
return std::unique_ptr<ui::LinuxInputMethodContext>( return std::unique_ptr<ui::LinuxInputMethodContext>(
new X11InputMethodContextImplGtk2(delegate, is_simple)); new X11InputMethodContextImplGtk(delegate, is_simple));
} }
gfx::FontRenderParams GtkUi::GetDefaultFontRenderParams() const { gfx::FontRenderParams GtkUi::GetDefaultFontRenderParams() const {
@@ -845,7 +779,7 @@ bool GtkUi::PreferDarkTheme() const {
#if BUILDFLAG(ENABLE_NATIVE_WINDOW_NAV_BUTTONS) #if BUILDFLAG(ENABLE_NATIVE_WINDOW_NAV_BUTTONS)
std::unique_ptr<views::NavButtonProvider> GtkUi::CreateNavButtonProvider() { std::unique_ptr<views::NavButtonProvider> GtkUi::CreateNavButtonProvider() {
if (GtkVersionCheck(3, 14)) if (GtkVersionCheck(3, 14))
return std::make_unique<libgtkui::NavButtonProviderGtk3>(); return std::make_unique<libgtkui::NavButtonProviderGtk>();
return nullptr; return nullptr;
} }
#endif #endif
@@ -911,7 +845,7 @@ bool GtkUi::MatchEvent(const ui::Event& event,
std::vector<ui::TextEditCommandAuraLinux>* commands) { std::vector<ui::TextEditCommandAuraLinux>* commands) {
// Ensure that we have a keyboard handler. // Ensure that we have a keyboard handler.
if (!key_bindings_handler_) if (!key_bindings_handler_)
key_bindings_handler_.reset(new Gtk2KeyBindingsHandler); key_bindings_handler_.reset(new GtkKeyBindingsHandler);
return key_bindings_handler_->MatchEvent(event, commands); return key_bindings_handler_->MatchEvent(event, commands);
} }
@@ -921,13 +855,11 @@ void GtkUi::OnDeviceScaleFactorMaybeChanged(void*, GParamSpec*) {
} }
void GtkUi::SetScrollbarColors() { void GtkUi::SetScrollbarColors() {
// TODO(thomasanderson): Do not hardcode these values. Get them from the
// theme.
thumb_active_color_ = SkColorSetRGB(244, 244, 244); thumb_active_color_ = SkColorSetRGB(244, 244, 244);
thumb_inactive_color_ = SkColorSetRGB(234, 234, 234); thumb_inactive_color_ = SkColorSetRGB(234, 234, 234);
track_color_ = SkColorSetRGB(211, 211, 211); track_color_ = SkColorSetRGB(211, 211, 211);
GetChromeStyleColor("scrollbar-slider-prelight-color", &thumb_active_color_);
GetChromeStyleColor("scrollbar-slider-normal-color", &thumb_inactive_color_);
GetChromeStyleColor("scrollbar-trough-color", &track_color_);
} }
void GtkUi::LoadGtkValues() { void GtkUi::LoadGtkValues() {
@@ -939,66 +871,6 @@ void GtkUi::LoadGtkValues() {
UpdateDeviceScaleFactor(); UpdateDeviceScaleFactor();
UpdateCursorTheme(); UpdateCursorTheme();
#if GTK_MAJOR_VERSION == 2
const color_utils::HSL kDefaultFrameShift = {-1, -1, 0.4};
SkColor frame_color =
native_theme_->GetSystemColor(ui::NativeTheme::kColorId_WindowBackground);
frame_color = color_utils::HSLShift(frame_color, kDefaultFrameShift);
GetChromeStyleColor("frame-color", &frame_color);
colors_[ThemeProperties::COLOR_FRAME] = frame_color;
GtkStyle* style = gtk_rc_get_style(fake_window_);
SkColor temp_color = color_utils::HSLShift(
GdkColorToSkColor(style->bg[GTK_STATE_INSENSITIVE]), kDefaultFrameShift);
GetChromeStyleColor("inactive-frame-color", &temp_color);
colors_[ThemeProperties::COLOR_FRAME_INACTIVE] = temp_color;
temp_color = color_utils::HSLShift(frame_color, kDefaultTintFrameIncognito);
GetChromeStyleColor("incognito-frame-color", &temp_color);
colors_[ThemeProperties::COLOR_FRAME_INCOGNITO] = temp_color;
temp_color =
color_utils::HSLShift(frame_color, kDefaultTintFrameIncognitoInactive);
GetChromeStyleColor("incognito-inactive-frame-color", &temp_color);
colors_[ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE] = temp_color;
SkColor tab_color =
native_theme_->GetSystemColor(ui::NativeTheme::kColorId_DialogBackground);
SkColor label_color = native_theme_->GetSystemColor(
ui::NativeTheme::kColorId_LabelEnabledColor);
colors_[ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON] =
color_utils::DeriveDefaultIconColor(label_color);
colors_[ThemeProperties::COLOR_TAB_TEXT] = label_color;
colors_[ThemeProperties::COLOR_BOOKMARK_TEXT] = label_color;
colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] =
color_utils::BlendTowardOppositeLuma(label_color, 50);
inactive_selection_bg_color_ = native_theme_->GetSystemColor(
ui::NativeTheme::kColorId_TextfieldReadOnlyBackground);
inactive_selection_fg_color_ = native_theme_->GetSystemColor(
ui::NativeTheme::kColorId_TextfieldReadOnlyColor);
// We pick the text and background colors for the NTP out of the
// colors for a GtkEntry. We do this because GtkEntries background
// color is never the same as |tab_color|, is usually a white,
// and when it isn't a white, provides sufficient contrast to
// |tab_color|. Try this out with Darklooks, HighContrastInverse
// or ThinIce.
colors_[ThemeProperties::COLOR_NTP_BACKGROUND] =
native_theme_->GetSystemColor(
ui::NativeTheme::kColorId_TextfieldDefaultBackground);
colors_[ThemeProperties::COLOR_NTP_TEXT] = native_theme_->GetSystemColor(
ui::NativeTheme::kColorId_TextfieldDefaultColor);
// The NTP header is the color that surrounds the current active
// thumbnail on the NTP, and acts as the border of the "Recent
// Links" box. It would be awesome if they were separated so we
// could use GetBorderColor() for the border around the "Recent
// Links" section, but matching the frame color is more important.
colors_[ThemeProperties::COLOR_NTP_HEADER] =
colors_[ThemeProperties::COLOR_FRAME];
#else
SkColor tab_color = GetBgColor(""); SkColor tab_color = GetBgColor("");
SkColor tab_text_color = GetFgColor("GtkLabel"); SkColor tab_text_color = GetFgColor("GtkLabel");
@@ -1164,7 +1036,6 @@ void GtkUi::LoadGtkValues() {
toolbar_top_separator_inactive; toolbar_top_separator_inactive;
} }
} }
#endif
colors_[ThemeProperties::COLOR_TOOLBAR] = tab_color; colors_[ThemeProperties::COLOR_TOOLBAR] = tab_color;
colors_[ThemeProperties::COLOR_CONTROL_BACKGROUND] = tab_color; colors_[ThemeProperties::COLOR_CONTROL_BACKGROUND] = tab_color;
@@ -1254,21 +1125,6 @@ void GtkUi::UpdateDefaultFont() {
g_object_unref(fake_label); g_object_unref(fake_label);
} }
bool GtkUi::GetChromeStyleColor(const char* style_property,
SkColor* ret_color) const {
#if GTK_MAJOR_VERSION == 2
GdkColor* style_color = nullptr;
gtk_widget_style_get(fake_window_, style_property, &style_color, nullptr);
if (style_color) {
*ret_color = GdkColorToSkColor(*style_color);
gdk_color_free(style_color);
return true;
}
#endif
return false;
}
void GtkUi::ResetStyle() { void GtkUi::ResetStyle() {
LoadGtkValues(); LoadGtkValues();
native_theme_->NotifyObservers(); native_theme_->NotifyObservers();
@@ -1278,19 +1134,12 @@ float GtkUi::GetRawDeviceScaleFactor() {
if (display::Display::HasForceDeviceScaleFactor()) if (display::Display::HasForceDeviceScaleFactor())
return display::Display::GetForcedDeviceScaleFactor(); return display::Display::GetForcedDeviceScaleFactor();
#if GTK_MAJOR_VERSION == 2
GtkSettings* gtk_settings = gtk_settings_get_default();
gint gtk_dpi = -1;
g_object_get(gtk_settings, "gtk-xft-dpi", &gtk_dpi, nullptr);
const float scale_factor = gtk_dpi / (1024 * kDefaultDPI);
#else
GdkScreen* screen = gdk_screen_get_default(); GdkScreen* screen = gdk_screen_get_default();
gint scale = gtk_widget_get_scale_factor(fake_window_); gint scale = gtk_widget_get_scale_factor(fake_window_);
DCHECK_GT(scale, 0); DCHECK_GT(scale, 0);
gdouble resolution = gdk_screen_get_resolution(screen); gdouble resolution = gdk_screen_get_resolution(screen);
const float scale_factor = const float scale_factor =
resolution <= 0 ? scale : resolution * scale / kDefaultDPI; resolution <= 0 ? scale : resolution * scale / kDefaultDPI;
#endif
// Blacklist scaling factors <120% (crbug.com/484400) and round // Blacklist scaling factors <120% (crbug.com/484400) and round
// to 1 decimal to prevent rendering problems (crbug.com/485183). // to 1 decimal to prevent rendering problems (crbug.com/485183).

@@ -26,7 +26,7 @@ typedef struct _GtkWidget GtkWidget;
namespace libgtkui { namespace libgtkui {
using ColorMap = std::map<int, SkColor>; using ColorMap = std::map<int, SkColor>;
class Gtk2KeyBindingsHandler; class GtkKeyBindingsHandler;
class DeviceScaleFactorObserver; class DeviceScaleFactorObserver;
class SettingsProvider; class SettingsProvider;
@@ -145,16 +145,11 @@ class GtkUi : public views::LinuxUI {
// Updates |default_font_*|. // Updates |default_font_*|.
void UpdateDefaultFont(); void UpdateDefaultFont();
// Gets a ChromeGtkFrame theme color; returns true on success. No-op on gtk3.
bool GetChromeStyleColor(const char* sytle_property,
SkColor* ret_color) const;
float GetRawDeviceScaleFactor(); float GetRawDeviceScaleFactor();
ui::NativeTheme* native_theme_; ui::NativeTheme* native_theme_;
// On Gtk2, A GtkWindow object with the class "ChromeGtkFrame". On // A regular GtkWindow.
// Gtk3, a regular GtkWindow.
GtkWidget* fake_window_; GtkWidget* fake_window_;
// Colors calculated by LoadGtkValues() that are given to the // Colors calculated by LoadGtkValues() that are given to the
@@ -196,7 +191,7 @@ class GtkUi : public views::LinuxUI {
std::vector<views::FrameButton> leading_buttons_; std::vector<views::FrameButton> leading_buttons_;
std::vector<views::FrameButton> trailing_buttons_; std::vector<views::FrameButton> trailing_buttons_;
std::unique_ptr<Gtk2KeyBindingsHandler> key_bindings_handler_; std::unique_ptr<GtkKeyBindingsHandler> key_bindings_handler_;
// Objects to notify when the window frame button order changes. // Objects to notify when the window frame button order changes.
base::ObserverList<views::WindowButtonOrderObserver>::Unchecked base::ObserverList<views::WindowButtonOrderObserver>::Unchecked
@@ -211,7 +206,7 @@ class GtkUi : public views::LinuxUI {
window_frame_actions_[WINDOW_FRAME_ACTION_SOURCE_LAST]; window_frame_actions_[WINDOW_FRAME_ACTION_SOURCE_LAST];
// Used to override the native theme for a window. If no override is provided // Used to override the native theme for a window. If no override is provided
// or the callback returns nullptr, GtkUi will default to a NativeThemeGtk2 // or the callback returns nullptr, GtkUi will default to a NativeThemeGtk
// instance. // instance.
NativeThemeGetter native_theme_overrider_; NativeThemeGetter native_theme_overrider_;
@@ -222,11 +217,7 @@ class GtkUi : public views::LinuxUI {
} // namespace libgtkui } // namespace libgtkui
// Access point to the GTK2 desktop system. This should be the only symbol that // Access point to the GTK desktop system.
// is exported in the library; everything else should be used through the
// interface, because eventually this .so will be loaded through dlopen at
// runtime so our main binary can conditionally load GTK2 or GTK3 or EFL or
// QT or whatever.
LIBGTKUI_EXPORT views::LinuxUI* BuildGtkUi(); LIBGTKUI_EXPORT views::LinuxUI* BuildGtkUi();
#endif // CHROME_BROWSER_UI_LIBGTKUI_GTK_UI_H_ #endif // CHROME_BROWSER_UI_LIBGTKUI_GTK_UI_H_

@@ -168,12 +168,8 @@ int EventFlagsFromGdkState(guint state) {
} }
void TurnButtonBlue(GtkWidget* button) { void TurnButtonBlue(GtkWidget* button) {
#if GTK_MAJOR_VERSION == 2
gtk_widget_set_can_default(button, true);
#else
gtk_style_context_add_class(gtk_widget_get_style_context(button), gtk_style_context_add_class(gtk_widget_get_style_context(button),
"suggested-action"); "suggested-action");
#endif
} }
void SetGtkTransientForAura(GtkWidget* dialog, aura::Window* parent) { void SetGtkTransientForAura(GtkWidget* dialog, aura::Window* parent) {
@@ -231,7 +227,6 @@ void ParseButtonLayout(const std::string& button_string,
} }
} }
#if GTK_MAJOR_VERSION > 2
namespace { namespace {
float GetDeviceScaleFactor() { float GetDeviceScaleFactor() {
@@ -621,6 +616,5 @@ SkColor GetSeparatorColor(const std::string& css_selector) {
gtk_render_frame(context, surface.cairo(), 0, 0, w, h); gtk_render_frame(context, surface.cairo(), 0, 0, w, h);
return surface.GetAveragePixelValue(false); return surface.GetAveragePixelValue(false);
} }
#endif
} // namespace libgtkui } // namespace libgtkui

@@ -84,12 +84,11 @@ void ClearAuraTransientParent(GtkWidget* dialog);
// Parses |button_string| into |leading_buttons| and // Parses |button_string| into |leading_buttons| and
// |trailing_buttons|. The string is of the format // |trailing_buttons|. The string is of the format
// "<button>*:<button*>", for example, "close:minimize:maximize". // "<button>*:<button*>", for example, "close:minimize:maximize".
// This format is used by GTK3 settings and gsettings. // This format is used by GTK settings and gsettings.
void ParseButtonLayout(const std::string& button_string, void ParseButtonLayout(const std::string& button_string,
std::vector<views::FrameButton>* leading_buttons, std::vector<views::FrameButton>* leading_buttons,
std::vector<views::FrameButton>* trailing_buttons); std::vector<views::FrameButton>* trailing_buttons);
#if GTK_MAJOR_VERSION > 2
void* GetGdkSharedLibrary(); void* GetGdkSharedLibrary();
void* GetGtkSharedLibrary(); void* GetGtkSharedLibrary();
@@ -206,7 +205,6 @@ SkColor GetSelectionBgColor(const std::string& css_selector);
// Get the color of the GtkSeparator specified by |css_selector|. // Get the color of the GtkSeparator specified by |css_selector|.
SkColor GetSeparatorColor(const std::string& css_selector); SkColor GetSeparatorColor(const std::string& css_selector);
#endif
} // namespace libgtkui } // namespace libgtkui

@@ -6,7 +6,7 @@
#define CHROME_BROWSER_UI_LIBGTKUI_LIBGTKUI_EXPORT_H_ #define CHROME_BROWSER_UI_LIBGTKUI_LIBGTKUI_EXPORT_H_
// Defines LIBGTKUI_EXPORT so that functionality implemented by our limited // Defines LIBGTKUI_EXPORT so that functionality implemented by our limited
// gtk2 module can be exported to consumers. // gtk module can be exported to consumers.
#if defined(COMPONENT_BUILD) #if defined(COMPONENT_BUILD)
#if defined(WIN32) #if defined(WIN32)

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/ui/libgtkui/native_theme_gtk3.h" #include "chrome/browser/ui/libgtkui/native_theme_gtk.h"
#include <gtk/gtk.h> #include <gtk/gtk.h>
@@ -406,12 +406,12 @@ SkColor SkColorFromColorId(ui::NativeTheme::ColorId color_id) {
} // namespace } // namespace
// static // static
NativeThemeGtk3* NativeThemeGtk3::instance() { NativeThemeGtk* NativeThemeGtk::instance() {
CR_DEFINE_STATIC_LOCAL(NativeThemeGtk3, s_native_theme, ()); CR_DEFINE_STATIC_LOCAL(NativeThemeGtk, s_native_theme, ());
return &s_native_theme; return &s_native_theme;
} }
NativeThemeGtk3::NativeThemeGtk3() { NativeThemeGtk::NativeThemeGtk() {
// These types are needed by g_type_from_name(), but may not be registered at // These types are needed by g_type_from_name(), but may not be registered at
// this point. We need the g_type_class magic to make sure the compiler // this point. We need the g_type_class magic to make sure the compiler
// doesn't optimize away this code. // doesn't optimize away this code.
@@ -440,11 +440,11 @@ NativeThemeGtk3::NativeThemeGtk3() {
OnThemeChanged(gtk_settings_get_default(), nullptr); OnThemeChanged(gtk_settings_get_default(), nullptr);
} }
NativeThemeGtk3::~NativeThemeGtk3() { NativeThemeGtk::~NativeThemeGtk() {
NOTREACHED(); NOTREACHED();
} }
void NativeThemeGtk3::SetThemeCssOverride(ScopedCssProvider provider) { void NativeThemeGtk::SetThemeCssOverride(ScopedCssProvider provider) {
if (theme_css_override_) { if (theme_css_override_) {
gtk_style_context_remove_provider_for_screen( gtk_style_context_remove_provider_for_screen(
gdk_screen_get_default(), gdk_screen_get_default(),
@@ -458,8 +458,8 @@ void NativeThemeGtk3::SetThemeCssOverride(ScopedCssProvider provider) {
} }
} }
void NativeThemeGtk3::OnThemeChanged(GtkSettings* settings, void NativeThemeGtk::OnThemeChanged(GtkSettings* settings,
GtkParamSpec* param) { GtkParamSpec* param) {
SetThemeCssOverride(ScopedCssProvider()); SetThemeCssOverride(ScopedCssProvider());
for (auto& color : color_cache_) for (auto& color : color_cache_)
color = base::nullopt; color = base::nullopt;
@@ -479,7 +479,7 @@ void NativeThemeGtk3::OnThemeChanged(GtkSettings* settings,
} }
} }
SkColor NativeThemeGtk3::GetSystemColor(ColorId color_id) const { SkColor NativeThemeGtk::GetSystemColor(ColorId color_id) const {
if (color_cache_[color_id]) if (color_cache_[color_id])
return color_cache_[color_id].value(); return color_cache_[color_id].value();
@@ -488,10 +488,10 @@ SkColor NativeThemeGtk3::GetSystemColor(ColorId color_id) const {
return color; return color;
} }
void NativeThemeGtk3::PaintArrowButton(cc::PaintCanvas* canvas, void NativeThemeGtk::PaintArrowButton(cc::PaintCanvas* canvas,
const gfx::Rect& rect, const gfx::Rect& rect,
Part direction, Part direction,
State state) const { State state) const {
auto context = GetStyleContextFromCss( auto context = GetStyleContextFromCss(
GtkVersionCheck(3, 20) GtkVersionCheck(3, 20)
? "GtkScrollbar#scrollbar #contents GtkButton#button" ? "GtkScrollbar#scrollbar #contents GtkButton#button"
@@ -520,20 +520,21 @@ void NativeThemeGtk3::PaintArrowButton(cc::PaintCanvas* canvas,
PaintArrow(canvas, rect, direction, GetFgColorFromStyleContext(context)); PaintArrow(canvas, rect, direction, GetFgColorFromStyleContext(context));
} }
void NativeThemeGtk3::PaintScrollbarTrack( void NativeThemeGtk::PaintScrollbarTrack(
cc::PaintCanvas* canvas, cc::PaintCanvas* canvas,
Part part, Part part,
State state, State state,
const ScrollbarTrackExtraParams& extra_params, const ScrollbarTrackExtraParams& extra_params,
const gfx::Rect& rect) const { const gfx::Rect& rect) const {
PaintWidget(canvas, rect, GetStyleContextFromCss( PaintWidget(
GtkVersionCheck(3, 20) canvas, rect,
? "GtkScrollbar#scrollbar #contents #trough" GetStyleContextFromCss(GtkVersionCheck(3, 20)
: "GtkScrollbar.scrollbar.trough"), ? "GtkScrollbar#scrollbar #contents #trough"
BG_RENDER_NORMAL, true); : "GtkScrollbar.scrollbar.trough"),
BG_RENDER_NORMAL, true);
} }
void NativeThemeGtk3::PaintScrollbarThumb( void NativeThemeGtk::PaintScrollbarThumb(
cc::PaintCanvas* canvas, cc::PaintCanvas* canvas,
Part part, Part part,
State state, State state,
@@ -547,9 +548,9 @@ void NativeThemeGtk3::PaintScrollbarThumb(
PaintWidget(canvas, rect, context, BG_RENDER_NORMAL, true); PaintWidget(canvas, rect, context, BG_RENDER_NORMAL, true);
} }
void NativeThemeGtk3::PaintScrollbarCorner(cc::PaintCanvas* canvas, void NativeThemeGtk::PaintScrollbarCorner(cc::PaintCanvas* canvas,
State state, State state,
const gfx::Rect& rect) const { const gfx::Rect& rect) const {
auto context = GetStyleContextFromCss( auto context = GetStyleContextFromCss(
GtkVersionCheck(3, 19, 2) GtkVersionCheck(3, 19, 2)
? "GtkScrolledWindow#scrolledwindow #junction" ? "GtkScrolledWindow#scrolledwindow #junction"
@@ -557,7 +558,7 @@ void NativeThemeGtk3::PaintScrollbarCorner(cc::PaintCanvas* canvas,
PaintWidget(canvas, rect, context, BG_RENDER_NORMAL, true); PaintWidget(canvas, rect, context, BG_RENDER_NORMAL, true);
} }
void NativeThemeGtk3::PaintMenuPopupBackground( void NativeThemeGtk::PaintMenuPopupBackground(
cc::PaintCanvas* canvas, cc::PaintCanvas* canvas,
const gfx::Size& size, const gfx::Size& size,
const MenuBackgroundExtraParams& menu_background) const { const MenuBackgroundExtraParams& menu_background) const {
@@ -565,7 +566,7 @@ void NativeThemeGtk3::PaintMenuPopupBackground(
BG_RENDER_RECURSIVE, false); BG_RENDER_RECURSIVE, false);
} }
void NativeThemeGtk3::PaintMenuItemBackground( void NativeThemeGtk::PaintMenuItemBackground(
cc::PaintCanvas* canvas, cc::PaintCanvas* canvas,
State state, State state,
const gfx::Rect& rect, const gfx::Rect& rect,
@@ -575,7 +576,7 @@ void NativeThemeGtk3::PaintMenuItemBackground(
PaintWidget(canvas, rect, context, BG_RENDER_NORMAL, true); PaintWidget(canvas, rect, context, BG_RENDER_NORMAL, true);
} }
void NativeThemeGtk3::PaintMenuSeparator( void NativeThemeGtk::PaintMenuSeparator(
cc::PaintCanvas* canvas, cc::PaintCanvas* canvas,
State state, State state,
const gfx::Rect& rect, const gfx::Rect& rect,
@@ -646,7 +647,7 @@ void NativeThemeGtk3::PaintMenuSeparator(
} }
} }
void NativeThemeGtk3::PaintFrameTopArea( void NativeThemeGtk::PaintFrameTopArea(
cc::PaintCanvas* canvas, cc::PaintCanvas* canvas,
State state, State state,
const gfx::Rect& rect, const gfx::Rect& rect,

@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_LIBGTKUI_NATIVE_THEME_GTK3_H_ #ifndef CHROME_BROWSER_UI_LIBGTKUI_NATIVE_THEME_GTK_H_
#define CHROME_BROWSER_UI_LIBGTKUI_NATIVE_THEME_GTK3_H_ #define CHROME_BROWSER_UI_LIBGTKUI_NATIVE_THEME_GTK_H_
#include "base/macros.h" #include "base/macros.h"
#include "base/optional.h" #include "base/optional.h"
@@ -19,10 +19,10 @@ namespace libgtkui {
using ScopedCssProvider = ScopedGObject<GtkCssProvider>; using ScopedCssProvider = ScopedGObject<GtkCssProvider>;
// A version of NativeTheme that uses GTK3-rendered widgets. // A version of NativeTheme that uses GTK-rendered widgets.
class NativeThemeGtk3 : public ui::NativeThemeBase { class NativeThemeGtk : public ui::NativeThemeBase {
public: public:
static NativeThemeGtk3* instance(); static NativeThemeGtk* instance();
// Overridden from ui::NativeThemeBase: // Overridden from ui::NativeThemeBase:
SkColor GetSystemColor(ColorId color_id) const override; SkColor GetSystemColor(ColorId color_id) const override;
@@ -65,12 +65,12 @@ class NativeThemeGtk3 : public ui::NativeThemeBase {
const FrameTopAreaExtraParams& frame_top_area) const override; const FrameTopAreaExtraParams& frame_top_area) const override;
private: private:
NativeThemeGtk3(); NativeThemeGtk();
~NativeThemeGtk3() override; ~NativeThemeGtk() override;
void SetThemeCssOverride(ScopedCssProvider provider); void SetThemeCssOverride(ScopedCssProvider provider);
CHROMEG_CALLBACK_1(NativeThemeGtk3, CHROMEG_CALLBACK_1(NativeThemeGtk,
void, void,
OnThemeChanged, OnThemeChanged,
GtkSettings*, GtkSettings*,
@@ -80,9 +80,9 @@ class NativeThemeGtk3 : public ui::NativeThemeBase {
ScopedCssProvider theme_css_override_; ScopedCssProvider theme_css_override_;
DISALLOW_COPY_AND_ASSIGN(NativeThemeGtk3); DISALLOW_COPY_AND_ASSIGN(NativeThemeGtk);
}; };
} // namespace libgtkui } // namespace libgtkui
#endif // CHROME_BROWSER_UI_LIBGTKUI_NATIVE_THEME_GTK3_H_ #endif // CHROME_BROWSER_UI_LIBGTKUI_NATIVE_THEME_GTK_H_

@@ -1,474 +0,0 @@
// Copyright (c) 2013 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 "chrome/browser/ui/libgtkui/native_theme_gtk2.h"
#include <gtk/gtk.h>
#include "chrome/browser/ui/libgtkui/chrome_gtk_frame.h"
#include "chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.h"
#include "chrome/browser/ui/libgtkui/gtk_ui.h"
#include "chrome/browser/ui/libgtkui/gtk_util.h"
#include "chrome/browser/ui/libgtkui/skia_utils_gtk.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/path.h"
#include "ui/gfx/skia_util.h"
#include "ui/native_theme/common_theme.h"
#include "ui/native_theme/native_theme_aura.h"
#include "ui/native_theme/native_theme_dark_aura.h"
namespace libgtkui {
namespace {
enum WidgetState {
NORMAL = 0,
ACTIVE = 1,
PRELIGHT = 2,
SELECTED = 3,
INSENSITIVE = 4,
};
// Same order as enum WidgetState above
const GtkStateType stateMap[] = {
GTK_STATE_NORMAL, GTK_STATE_ACTIVE, GTK_STATE_PRELIGHT,
GTK_STATE_SELECTED, GTK_STATE_INSENSITIVE,
};
SkColor GetFgColor(GtkWidget* widget, WidgetState state) {
return GdkColorToSkColor(gtk_rc_get_style(widget)->fg[stateMap[state]]);
}
SkColor GetBgColor(GtkWidget* widget, WidgetState state) {
return GdkColorToSkColor(gtk_rc_get_style(widget)->bg[stateMap[state]]);
}
SkColor GetTextColor(GtkWidget* widget, WidgetState state) {
return GdkColorToSkColor(gtk_rc_get_style(widget)->text[stateMap[state]]);
}
SkColor GetTextAAColor(GtkWidget* widget, WidgetState state) {
return GdkColorToSkColor(gtk_rc_get_style(widget)->text_aa[stateMap[state]]);
}
SkColor GetBaseColor(GtkWidget* widget, WidgetState state) {
return GdkColorToSkColor(gtk_rc_get_style(widget)->base[stateMap[state]]);
}
} // namespace
// static
NativeThemeGtk2* NativeThemeGtk2::instance() {
CR_DEFINE_STATIC_LOCAL(NativeThemeGtk2, s_native_theme, ());
return &s_native_theme;
}
// Constructors automatically called
NativeThemeGtk2::NativeThemeGtk2() {}
// This doesn't actually get called
NativeThemeGtk2::~NativeThemeGtk2() {}
void NativeThemeGtk2::PaintMenuPopupBackground(
cc::PaintCanvas* canvas,
const gfx::Size& size,
const MenuBackgroundExtraParams& menu_background) const {
if (menu_background.corner_radius > 0) {
cc::PaintFlags flags;
flags.setStyle(cc::PaintFlags::kFill_Style);
flags.setAntiAlias(true);
flags.setColor(GetSystemColor(kColorId_MenuBackgroundColor));
gfx::Path path;
SkRect rect = SkRect::MakeWH(SkIntToScalar(size.width()),
SkIntToScalar(size.height()));
SkScalar radius = SkIntToScalar(menu_background.corner_radius);
SkScalar radii[8] = {radius, radius, radius, radius,
radius, radius, radius, radius};
path.addRoundRect(rect, radii);
canvas->drawPath(path, flags);
} else {
canvas->drawColor(GetSystemColor(kColorId_MenuBackgroundColor),
SkBlendMode::kSrc);
}
}
void NativeThemeGtk2::PaintMenuItemBackground(
cc::PaintCanvas* canvas,
State state,
const gfx::Rect& rect,
const MenuItemExtraParams& menu_item) const {
SkColor color;
cc::PaintFlags flags;
switch (state) {
case NativeTheme::kNormal:
case NativeTheme::kDisabled:
color = GetSystemColor(NativeTheme::kColorId_MenuBackgroundColor);
flags.setColor(color);
break;
case NativeTheme::kHovered:
color =
GetSystemColor(NativeTheme::kColorId_FocusedMenuItemBackgroundColor);
flags.setColor(color);
break;
default:
NOTREACHED() << "Invalid state " << state;
break;
}
if (menu_item.corner_radius > 0) {
const SkScalar radius = SkIntToScalar(menu_item.corner_radius);
canvas->drawRoundRect(gfx::RectToSkRect(rect), radius, radius, flags);
return;
}
canvas->drawRect(gfx::RectToSkRect(rect), flags);
}
SkColor NativeThemeGtk2::GetSystemColor(ColorId color_id) const {
const SkColor kPositiveTextColor = SkColorSetRGB(0x0b, 0x80, 0x43);
const SkColor kNegativeTextColor = SkColorSetRGB(0xc5, 0x39, 0x29);
switch (color_id) {
// Windows
case kColorId_WindowBackground:
return GetBgColor(GetWindow(), SELECTED);
// Dialogs
case kColorId_DialogBackground:
case kColorId_BubbleBackground:
return GetBgColor(GetWindow(), NORMAL);
// FocusableBorder
case kColorId_FocusedBorderColor:
return GetBgColor(GetEntry(), SELECTED);
case kColorId_UnfocusedBorderColor:
return GetTextAAColor(GetEntry(), NORMAL);
// MenuItem
case kColorId_SelectedMenuItemForegroundColor:
return GetTextColor(GetMenuItem(), SELECTED);
case kColorId_FocusedMenuItemBackgroundColor:
return GetBgColor(GetMenuItem(), SELECTED);
case kColorId_EnabledMenuItemForegroundColor:
return GetTextColor(GetMenuItem(), NORMAL);
case kColorId_MenuItemMinorTextColor:
case kColorId_DisabledMenuItemForegroundColor:
return GetTextColor(GetMenuItem(), INSENSITIVE);
case kColorId_MenuBorderColor:
case kColorId_MenuSeparatorColor:
return GetTextColor(GetMenuItem(), INSENSITIVE);
case kColorId_MenuBackgroundColor:
return GetBgColor(GetMenu(), NORMAL);
case kColorId_TouchableMenuItemLabelColor:
case kColorId_ActionableSubmenuVerticalSeparatorColor:
return kInvalidColorIdColor;
// Label
case kColorId_LabelEnabledColor:
return GetTextColor(GetEntry(), NORMAL);
case kColorId_LabelDisabledColor:
return GetTextColor(GetLabel(), INSENSITIVE);
case kColorId_LabelTextSelectionColor:
return GetTextColor(GetLabel(), SELECTED);
case kColorId_LabelTextSelectionBackgroundFocused:
return GetBaseColor(GetLabel(), SELECTED);
// Link
case kColorId_LinkDisabled:
return SkColorSetA(GetSystemColor(kColorId_LinkEnabled), 0xBB);
case kColorId_LinkEnabled: {
SkColor link_color = SK_ColorTRANSPARENT;
GdkColor* style_color = nullptr;
gtk_widget_style_get(GetWindow(), "link-color", &style_color, nullptr);
if (style_color) {
link_color = GdkColorToSkColor(*style_color);
gdk_color_free(style_color);
}
if (link_color != SK_ColorTRANSPARENT)
return link_color;
// Default color comes from gtklinkbutton.c.
return SkColorSetRGB(0x00, 0x00, 0xEE);
}
case kColorId_LinkPressed:
return SK_ColorRED;
// Separator
case kColorId_SeparatorColor:
return GetFgColor(GetSeparator(), INSENSITIVE);
// Button
case kColorId_ButtonEnabledColor:
return GetTextColor(GetButton(), NORMAL);
case kColorId_BlueButtonEnabledColor:
return GetTextColor(GetBlueButton(), NORMAL);
case kColorId_ButtonDisabledColor:
return GetTextColor(GetButton(), INSENSITIVE);
case kColorId_BlueButtonDisabledColor:
return GetTextColor(GetBlueButton(), INSENSITIVE);
case kColorId_ButtonHoverColor:
return GetTextColor(GetButton(), PRELIGHT);
case kColorId_BlueButtonHoverColor:
return GetTextColor(GetBlueButton(), PRELIGHT);
case kColorId_BlueButtonPressedColor:
return GetTextColor(GetBlueButton(), ACTIVE);
case kColorId_BlueButtonShadowColor:
return SK_ColorTRANSPARENT;
case kColorId_ProminentButtonColor:
return GetSystemColor(kColorId_LinkEnabled);
case kColorId_TextOnProminentButtonColor:
return GetTextColor(GetLabel(), SELECTED);
case kColorId_ButtonPressedShade:
return SK_ColorTRANSPARENT;
// TabbedPane
case ui::NativeTheme::kColorId_TabTitleColorActive:
return GetTextColor(GetEntry(), NORMAL);
case ui::NativeTheme::kColorId_TabTitleColorInactive:
return GetTextColor(GetLabel(), INSENSITIVE);
case ui::NativeTheme::kColorId_TabBottomBorder:
return GetTextColor(GetEntry(), NORMAL);
// Textfield
case kColorId_TextfieldDefaultColor:
return GetTextColor(GetEntry(), NORMAL);
case kColorId_TextfieldDefaultBackground:
return GetBaseColor(GetEntry(), NORMAL);
case kColorId_TextfieldReadOnlyColor:
return GetTextColor(GetEntry(), ACTIVE);
case kColorId_TextfieldReadOnlyBackground:
return GetBaseColor(GetEntry(), ACTIVE);
case kColorId_TextfieldSelectionColor:
return GetTextColor(GetEntry(), SELECTED);
case kColorId_TextfieldSelectionBackgroundFocused:
return GetBaseColor(GetEntry(), SELECTED);
// Tooltips
case kColorId_TooltipBackground:
return GetBgColor(GetTooltip(), NORMAL);
case kColorId_TooltipText:
return GetFgColor(GetTooltip(), NORMAL);
// Trees and Tables (implemented on GTK using the same class)
case kColorId_TableBackground:
case kColorId_TreeBackground:
return GetBgColor(GetTree(), NORMAL);
case kColorId_TableText:
case kColorId_TreeText:
return GetTextColor(GetTree(), NORMAL);
case kColorId_TableSelectedText:
case kColorId_TableSelectedTextUnfocused:
case kColorId_TreeSelectedText:
case kColorId_TreeSelectedTextUnfocused:
return GetTextColor(GetTree(), SELECTED);
case kColorId_TableSelectionBackgroundFocused:
case kColorId_TableSelectionBackgroundUnfocused:
case kColorId_TreeSelectionBackgroundFocused:
case kColorId_TreeSelectionBackgroundUnfocused:
return GetBgColor(GetTree(), SELECTED);
case kColorId_TableGroupingIndicatorColor:
return GetTextAAColor(GetTree(), NORMAL);
// Table Headers
case kColorId_TableHeaderText:
return GetTextColor(GetTree(), NORMAL);
case kColorId_TableHeaderBackground:
return GetBgColor(GetTree(), NORMAL);
case kColorId_TableHeaderSeparator:
return GetFgColor(GetSeparator(), INSENSITIVE);
// Results Table
case kColorId_ResultsTableNormalBackground:
return GetSystemColor(kColorId_TextfieldDefaultBackground);
case kColorId_ResultsTableHoveredBackground:
return color_utils::AlphaBlend(
GetSystemColor(kColorId_TextfieldDefaultBackground),
GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused), 0x80);
case kColorId_ResultsTableSelectedBackground:
return GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused);
case kColorId_ResultsTableNormalText:
case kColorId_ResultsTableHoveredText:
return GetSystemColor(kColorId_TextfieldDefaultColor);
case kColorId_ResultsTableSelectedText:
return GetSystemColor(kColorId_TextfieldSelectionColor);
case kColorId_ResultsTableNormalDimmedText:
case kColorId_ResultsTableHoveredDimmedText:
return color_utils::AlphaBlend(
GetSystemColor(kColorId_TextfieldDefaultColor),
GetSystemColor(kColorId_TextfieldDefaultBackground), 0x80);
case kColorId_ResultsTableSelectedDimmedText:
return color_utils::AlphaBlend(
GetSystemColor(kColorId_TextfieldSelectionColor),
GetSystemColor(kColorId_TextfieldDefaultBackground), 0x80);
case kColorId_ResultsTableNormalUrl:
case kColorId_ResultsTableHoveredUrl:
return NormalURLColor(GetSystemColor(kColorId_TextfieldDefaultColor));
case kColorId_ResultsTableSelectedUrl:
return SelectedURLColor(
GetSystemColor(kColorId_TextfieldSelectionColor),
GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused));
case kColorId_ResultsTablePositiveText: {
return color_utils::GetReadableColor(kPositiveTextColor,
GetBaseColor(GetEntry(), NORMAL));
}
case kColorId_ResultsTablePositiveHoveredText: {
return color_utils::GetReadableColor(kPositiveTextColor,
GetBaseColor(GetEntry(), PRELIGHT));
}
case kColorId_ResultsTablePositiveSelectedText: {
return color_utils::GetReadableColor(kPositiveTextColor,
GetBaseColor(GetEntry(), SELECTED));
}
case kColorId_ResultsTableNegativeText: {
return color_utils::GetReadableColor(kNegativeTextColor,
GetBaseColor(GetEntry(), NORMAL));
}
case kColorId_ResultsTableNegativeHoveredText: {
return color_utils::GetReadableColor(kNegativeTextColor,
GetBaseColor(GetEntry(), PRELIGHT));
}
case kColorId_ResultsTableNegativeSelectedText: {
return color_utils::GetReadableColor(kNegativeTextColor,
GetBaseColor(GetEntry(), SELECTED));
}
// Throbber
case kColorId_ThrobberSpinningColor:
case kColorId_ThrobberLightColor:
return GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused);
case kColorId_ThrobberWaitingColor:
return color_utils::AlphaBlend(
GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused),
GetBgColor(GetWindow(), NORMAL), 0x80);
// Alert icons
// Just fall back to the same colors as Aura.
case kColorId_AlertSeverityLow:
case kColorId_AlertSeverityMedium:
case kColorId_AlertSeverityHigh: {
ui::NativeTheme* fallback_theme =
color_utils::IsDark(GetTextColor(GetEntry(), NORMAL))
? ui::NativeTheme::GetInstanceForNativeUi()
: ui::NativeThemeDarkAura::instance();
return fallback_theme->GetSystemColor(color_id);
}
case kColorId_NumColors:
NOTREACHED();
break;
}
return kInvalidColorIdColor;
}
GtkWidget* NativeThemeGtk2::GetWindow() const {
static GtkWidget* fake_window = nullptr;
if (!fake_window) {
fake_window = chrome_gtk_frame_new();
gtk_widget_realize(fake_window);
}
return fake_window;
}
GtkWidget* NativeThemeGtk2::GetEntry() const {
static GtkWidget* fake_entry = nullptr;
if (!fake_entry) {
fake_entry = gtk_entry_new();
// The fake entry needs to be in the window so it can be realized so we can
// use the computed parts of the style.
gtk_container_add(GTK_CONTAINER(GetWindow()), fake_entry);
gtk_widget_realize(fake_entry);
}
return fake_entry;
}
GtkWidget* NativeThemeGtk2::GetLabel() const {
static GtkWidget* fake_label = nullptr;
if (!fake_label)
fake_label = gtk_label_new("");
return fake_label;
}
GtkWidget* NativeThemeGtk2::GetButton() const {
static GtkWidget* fake_button = nullptr;
if (!fake_button)
fake_button = gtk_button_new();
return fake_button;
}
GtkWidget* NativeThemeGtk2::GetBlueButton() const {
static GtkWidget* fake_bluebutton = nullptr;
if (!fake_bluebutton) {
fake_bluebutton = gtk_button_new();
TurnButtonBlue(fake_bluebutton);
}
return fake_bluebutton;
}
GtkWidget* NativeThemeGtk2::GetTree() const {
static GtkWidget* fake_tree = nullptr;
if (!fake_tree)
fake_tree = gtk_tree_view_new();
return fake_tree;
}
GtkWidget* NativeThemeGtk2::GetTooltip() const {
static GtkWidget* fake_tooltip = nullptr;
if (!fake_tooltip) {
fake_tooltip = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_name(fake_tooltip, "gtk-tooltip");
gtk_widget_realize(fake_tooltip);
}
return fake_tooltip;
}
GtkWidget* NativeThemeGtk2::GetMenu() const {
static GtkWidget* fake_menu = nullptr;
if (!fake_menu)
fake_menu = gtk_custom_menu_new();
return fake_menu;
}
GtkWidget* NativeThemeGtk2::GetMenuItem() const {
static GtkWidget* fake_menu_item = nullptr;
if (!fake_menu_item) {
fake_menu_item = gtk_custom_menu_item_new();
gtk_menu_shell_append(GTK_MENU_SHELL(GetMenu()), fake_menu_item);
}
return fake_menu_item;
}
GtkWidget* NativeThemeGtk2::GetSeparator() const {
static GtkWidget* fake_separator = nullptr;
if (!fake_separator)
fake_separator = gtk_hseparator_new();
return fake_separator;
}
} // namespace libgtkui

@@ -1,55 +0,0 @@
// Copyright (c) 2013 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 CHROME_BROWSER_UI_LIBGTKUI_NATIVE_THEME_GTK2_H_
#define CHROME_BROWSER_UI_LIBGTKUI_NATIVE_THEME_GTK2_H_
#include "base/macros.h"
#include "ui/native_theme/native_theme_base.h"
typedef struct _GtkWidget GtkWidget;
namespace libgtkui {
// A version of NativeTheme that uses GTK2 supplied colours instead of the
// default aura colours. Analogue to NativeThemeWin, except that can't be
// compiled into the main chrome binary like the Windows code can.
class NativeThemeGtk2 : public ui::NativeThemeBase {
public:
static NativeThemeGtk2* instance();
// Overridden from ui::NativeThemeBase:
SkColor GetSystemColor(ColorId color_id) const override;
void PaintMenuPopupBackground(
cc::PaintCanvas* canvas,
const gfx::Size& size,
const MenuBackgroundExtraParams& menu_background) const override;
void PaintMenuItemBackground(
cc::PaintCanvas* canvas,
State state,
const gfx::Rect& rect,
const MenuItemExtraParams& menu_item) const override;
private:
NativeThemeGtk2();
~NativeThemeGtk2() override;
// Returns various widgets for theming use.
GtkWidget* GetWindow() const;
GtkWidget* GetEntry() const;
GtkWidget* GetLabel() const;
GtkWidget* GetButton() const;
GtkWidget* GetBlueButton() const;
GtkWidget* GetTree() const;
GtkWidget* GetTooltip() const;
GtkWidget* GetMenu() const;
GtkWidget* GetMenuItem() const;
GtkWidget* GetSeparator() const;
DISALLOW_COPY_AND_ASSIGN(NativeThemeGtk2);
};
} // namespace libgtkui
#endif // CHROME_BROWSER_UI_LIBGTKUI_NATIVE_THEME_GTK2_H_

@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/ui/libgtkui/nav_button_provider_gtk3.h" #include "chrome/browser/ui/libgtkui/nav_button_provider_gtk.h"
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "chrome/browser/ui/libgtkui/gtk3_background_painter.h" #include "chrome/browser/ui/libgtkui/gtk_background_painter.h"
#include "chrome/browser/ui/libgtkui/gtk_util.h" #include "chrome/browser/ui/libgtkui/gtk_util.h"
#include "ui/base/glib/scoped_gobject.h" #include "ui/base/glib/scoped_gobject.h"
#include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia.h"
@@ -289,13 +289,13 @@ class NavButtonImageSource : public gfx::ImageSkiaSource {
} // namespace } // namespace
NavButtonProviderGtk3::NavButtonProviderGtk3() {} NavButtonProviderGtk::NavButtonProviderGtk() {}
NavButtonProviderGtk3::~NavButtonProviderGtk3() {} NavButtonProviderGtk::~NavButtonProviderGtk() {}
void NavButtonProviderGtk3::RedrawImages(int top_area_height, void NavButtonProviderGtk::RedrawImages(int top_area_height,
bool maximized, bool maximized,
bool active) { bool active) {
auto header_context = CreateHeaderContext(maximized); auto header_context = CreateHeaderContext(maximized);
GtkBorder header_padding; GtkBorder header_padding;
@@ -365,7 +365,7 @@ void NavButtonProviderGtk3::RedrawImages(int top_area_height,
} }
} }
gfx::ImageSkia NavButtonProviderGtk3::GetImage( gfx::ImageSkia NavButtonProviderGtk::GetImage(
chrome::FrameButtonDisplayType type, chrome::FrameButtonDisplayType type,
views::Button::ButtonState state) const { views::Button::ButtonState state) const {
auto it = button_images_.find(type); auto it = button_images_.find(type);
@@ -373,31 +373,31 @@ gfx::ImageSkia NavButtonProviderGtk3::GetImage(
return it->second[state]; return it->second[state];
} }
gfx::Insets NavButtonProviderGtk3::GetNavButtonMargin( gfx::Insets NavButtonProviderGtk::GetNavButtonMargin(
chrome::FrameButtonDisplayType type) const { chrome::FrameButtonDisplayType type) const {
auto it = button_margins_.find(type); auto it = button_margins_.find(type);
DCHECK(it != button_margins_.end()); DCHECK(it != button_margins_.end());
return it->second; return it->second;
} }
gfx::Insets NavButtonProviderGtk3::GetTopAreaSpacing() const { gfx::Insets NavButtonProviderGtk::GetTopAreaSpacing() const {
return top_area_spacing_; return top_area_spacing_;
} }
int NavButtonProviderGtk3::GetInterNavButtonSpacing() const { int NavButtonProviderGtk::GetInterNavButtonSpacing() const {
return inter_button_spacing_; return inter_button_spacing_;
} }
std::unique_ptr<views::Background> std::unique_ptr<views::Background>
NavButtonProviderGtk3::CreateAvatarButtonBackground( NavButtonProviderGtk::CreateAvatarButtonBackground(
const views::Button* avatar_button) const { const views::Button* avatar_button) const {
auto header_context = CreateHeaderContext(false); auto header_context = CreateHeaderContext(false);
auto button_context = CreateAvatarButtonContext(header_context); auto button_context = CreateAvatarButtonContext(header_context);
return std::make_unique<Gtk3BackgroundPainter>(avatar_button, return std::make_unique<GtkBackgroundPainter>(avatar_button,
std::move(button_context)); std::move(button_context));
} }
void NavButtonProviderGtk3::CalculateCaptionButtonLayout( void NavButtonProviderGtk::CalculateCaptionButtonLayout(
const gfx::Size& content_size, const gfx::Size& content_size,
int top_area_height, int top_area_height,
gfx::Size* caption_button_size, gfx::Size* caption_button_size,

@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_LIBGTKUI_NAV_BUTTON_PROVIDER_GTK3_H_ #ifndef CHROME_BROWSER_UI_LIBGTKUI_NAV_BUTTON_PROVIDER_GTK_H_
#define CHROME_BROWSER_UI_LIBGTKUI_NAV_BUTTON_PROVIDER_GTK3_H_ #define CHROME_BROWSER_UI_LIBGTKUI_NAV_BUTTON_PROVIDER_GTK_H_
#include <map> #include <map>
@@ -15,10 +15,10 @@
namespace libgtkui { namespace libgtkui {
class LIBGTKUI_EXPORT NavButtonProviderGtk3 : public views::NavButtonProvider { class LIBGTKUI_EXPORT NavButtonProviderGtk : public views::NavButtonProvider {
public: public:
NavButtonProviderGtk3(); NavButtonProviderGtk();
~NavButtonProviderGtk3() override; ~NavButtonProviderGtk() override;
// views::NavButtonProvider: // views::NavButtonProvider:
void RedrawImages(int top_area_height, bool maximized, bool active) override; void RedrawImages(int top_area_height, bool maximized, bool active) override;
@@ -47,4 +47,4 @@ class LIBGTKUI_EXPORT NavButtonProviderGtk3 : public views::NavButtonProvider {
} // namespace libgtkui } // namespace libgtkui
#endif // CHROME_BROWSER_UI_LIBGTKUI_NAV_BUTTON_PROVIDER_GTK3_H_ #endif // CHROME_BROWSER_UI_LIBGTKUI_NAV_BUTTON_PROVIDER_GTK_H_

@@ -171,20 +171,20 @@ class GtkPrinterList {
} // namespace } // namespace
// static // static
printing::PrintDialogGtkInterface* PrintDialogGtk2::CreatePrintDialog( printing::PrintDialogGtkInterface* PrintDialogGtk::CreatePrintDialog(
PrintingContextLinux* context) { PrintingContextLinux* context) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
return new PrintDialogGtk2(context); return new PrintDialogGtk(context);
} }
PrintDialogGtk2::PrintDialogGtk2(PrintingContextLinux* context) PrintDialogGtk::PrintDialogGtk(PrintingContextLinux* context)
: context_(context), : context_(context),
dialog_(nullptr), dialog_(nullptr),
gtk_settings_(nullptr), gtk_settings_(nullptr),
page_setup_(nullptr), page_setup_(nullptr),
printer_(nullptr) {} printer_(nullptr) {}
PrintDialogGtk2::~PrintDialogGtk2() { PrintDialogGtk::~PrintDialogGtk() {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (dialog_) { if (dialog_) {
@@ -210,7 +210,7 @@ PrintDialogGtk2::~PrintDialogGtk2() {
} }
} }
void PrintDialogGtk2::UseDefaultSettings() { void PrintDialogGtk::UseDefaultSettings() {
DCHECK(!page_setup_); DCHECK(!page_setup_);
DCHECK(!printer_); DCHECK(!printer_);
@@ -223,7 +223,7 @@ void PrintDialogGtk2::UseDefaultSettings() {
InitPrintSettings(&settings); InitPrintSettings(&settings);
} }
void PrintDialogGtk2::UpdateSettings(printing::PrintSettings* settings) { void PrintDialogGtk::UpdateSettings(printing::PrintSettings* settings) {
if (!gtk_settings_) { if (!gtk_settings_) {
gtk_settings_ = gtk_settings_ =
gtk_print_settings_copy(g_last_used_settings.Get().settings()); gtk_print_settings_copy(g_last_used_settings.Get().settings());
@@ -322,7 +322,7 @@ void PrintDialogGtk2::UpdateSettings(printing::PrintSettings* settings) {
InitPrintSettings(settings); InitPrintSettings(settings);
} }
void PrintDialogGtk2::ShowDialog( void PrintDialogGtk::ShowDialog(
gfx::NativeView parent_view, gfx::NativeView parent_view,
bool has_selection, bool has_selection,
PrintingContextLinux::PrintSettingsCallback callback) { PrintingContextLinux::PrintSettingsCallback callback) {
@@ -374,8 +374,8 @@ void PrintDialogGtk2::ShowDialog(
GTK_WINDOW(dialog_), ui::X11EventSource::GetInstance()->GetTimestamp()); GTK_WINDOW(dialog_), ui::X11EventSource::GetInstance()->GetTimestamp());
} }
void PrintDialogGtk2::PrintDocument(const printing::MetafilePlayer& metafile, void PrintDialogGtk::PrintDocument(const printing::MetafilePlayer& metafile,
const base::string16& document_name) { const base::string16& document_name) {
// This runs on the print worker thread, does not block the UI thread. // This runs on the print worker thread, does not block the UI thread.
DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -403,21 +403,20 @@ void PrintDialogGtk2::PrintDocument(const printing::MetafilePlayer& metafile,
} }
// No errors, continue printing. // No errors, continue printing.
BrowserThread::PostTask( BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
BrowserThread::UI, FROM_HERE, base::BindOnce(&PrintDialogGtk::SendDocumentToPrinter,
base::BindOnce(&PrintDialogGtk2::SendDocumentToPrinter, this, this, document_name));
document_name));
} }
void PrintDialogGtk2::AddRefToDialog() { void PrintDialogGtk::AddRefToDialog() {
AddRef(); AddRef();
} }
void PrintDialogGtk2::ReleaseDialog() { void PrintDialogGtk::ReleaseDialog() {
Release(); Release();
} }
void PrintDialogGtk2::OnResponse(GtkWidget* dialog, int response_id) { void PrintDialogGtk::OnResponse(GtkWidget* dialog, int response_id) {
int num_matched_handlers = g_signal_handlers_disconnect_by_func( int num_matched_handlers = g_signal_handlers_disconnect_by_func(
dialog_, reinterpret_cast<gpointer>(&OnResponseThunk), this); dialog_, reinterpret_cast<gpointer>(&OnResponseThunk), this);
CHECK_EQ(1, num_matched_handlers); CHECK_EQ(1, num_matched_handlers);
@@ -495,15 +494,11 @@ void PrintDialogGtk2::OnResponse(GtkWidget* dialog, int response_id) {
static void OnJobCompletedThunk(GtkPrintJob* print_job, static void OnJobCompletedThunk(GtkPrintJob* print_job,
gpointer user_data, gpointer user_data,
#if GTK_MAJOR_VERSION == 2
GError* error
#else
const GError* error const GError* error
#endif
) { ) {
static_cast<PrintDialogGtk2*>(user_data)->OnJobCompleted(print_job, error); static_cast<PrintDialogGtk*>(user_data)->OnJobCompleted(print_job, error);
} }
void PrintDialogGtk2::SendDocumentToPrinter( void PrintDialogGtk::SendDocumentToPrinter(
const base::string16& document_name) { const base::string16& document_name) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -526,8 +521,8 @@ void PrintDialogGtk2::SendDocumentToPrinter(
gtk_print_job_send(print_job, OnJobCompletedThunk, this, nullptr); gtk_print_job_send(print_job, OnJobCompletedThunk, this, nullptr);
} }
void PrintDialogGtk2::OnJobCompleted(GtkPrintJob* print_job, void PrintDialogGtk::OnJobCompleted(GtkPrintJob* print_job,
const GError* error) { const GError* error) {
if (error) if (error)
LOG(ERROR) << "Printing failed: " << error->message; LOG(ERROR) << "Printing failed: " << error->message;
if (print_job) if (print_job)
@@ -542,12 +537,12 @@ void PrintDialogGtk2::OnJobCompleted(GtkPrintJob* print_job,
Release(); Release();
} }
void PrintDialogGtk2::InitPrintSettings(PrintSettings* settings) { void PrintDialogGtk::InitPrintSettings(PrintSettings* settings) {
InitPrintSettingsGtk(gtk_settings_, page_setup_, settings); InitPrintSettingsGtk(gtk_settings_, page_setup_, settings);
context_->InitWithSettings(*settings); context_->InitWithSettings(*settings);
} }
void PrintDialogGtk2::OnWindowDestroying(aura::Window* window) { void PrintDialogGtk::OnWindowDestroying(aura::Window* window) {
DCHECK_EQ(libgtkui::GetAuraTransientParent(dialog_), window); DCHECK_EQ(libgtkui::GetAuraTransientParent(dialog_), window);
libgtkui::ClearAuraTransientParent(dialog_); libgtkui::ClearAuraTransientParent(dialog_);

@@ -27,11 +27,11 @@ class PrintSettings;
using printing::PrintingContextLinux; using printing::PrintingContextLinux;
// Needs to be freed on the UI thread to clean up its GTK members variables. // Needs to be freed on the UI thread to clean up its GTK members variables.
class PrintDialogGtk2 : public printing::PrintDialogGtkInterface, class PrintDialogGtk : public printing::PrintDialogGtkInterface,
public base::RefCountedThreadSafe< public base::RefCountedThreadSafe<
PrintDialogGtk2, PrintDialogGtk,
content::BrowserThread::DeleteOnUIThread>, content::BrowserThread::DeleteOnUIThread>,
public aura::WindowObserver { public aura::WindowObserver {
public: public:
// Creates and returns a print dialog. // Creates and returns a print dialog.
static printing::PrintDialogGtkInterface* CreatePrintDialog( static printing::PrintDialogGtkInterface* CreatePrintDialog(
@@ -55,13 +55,13 @@ class PrintDialogGtk2 : public printing::PrintDialogGtkInterface,
private: private:
friend struct content::BrowserThread::DeleteOnThread< friend struct content::BrowserThread::DeleteOnThread<
content::BrowserThread::UI>; content::BrowserThread::UI>;
friend class base::DeleteHelper<PrintDialogGtk2>; friend class base::DeleteHelper<PrintDialogGtk>;
explicit PrintDialogGtk2(PrintingContextLinux* context); explicit PrintDialogGtk(PrintingContextLinux* context);
~PrintDialogGtk2() override; ~PrintDialogGtk() override;
// Handles dialog response. // Handles dialog response.
CHROMEGTK_CALLBACK_1(PrintDialogGtk2, void, OnResponse, int); CHROMEGTK_CALLBACK_1(PrintDialogGtk, void, OnResponse, int);
// Prints document named |document_name|. // Prints document named |document_name|.
void SendDocumentToPrinter(const base::string16& document_name); void SendDocumentToPrinter(const base::string16& document_name);
@@ -77,7 +77,7 @@ class PrintDialogGtk2 : public printing::PrintDialogGtkInterface,
PrintingContextLinux::PrintSettingsCallback callback_; PrintingContextLinux::PrintSettingsCallback callback_;
PrintingContextLinux* context_; PrintingContextLinux* context_;
// Print dialog settings. PrintDialogGtk2 owns |dialog_| and holds references // Print dialog settings. PrintDialogGtk owns |dialog_| and holds references
// to the other objects. // to the other objects.
GtkWidget* dialog_; GtkWidget* dialog_;
GtkPrintSettings* gtk_settings_; GtkPrintSettings* gtk_settings_;
@@ -86,7 +86,7 @@ class PrintDialogGtk2 : public printing::PrintDialogGtkInterface,
base::FilePath path_to_pdf_; base::FilePath path_to_pdf_;
DISALLOW_COPY_AND_ASSIGN(PrintDialogGtk2); DISALLOW_COPY_AND_ASSIGN(PrintDialogGtk);
}; };
#endif // CHROME_BROWSER_UI_LIBGTKUI_PRINT_DIALOG_GTK_H_ #endif // CHROME_BROWSER_UI_LIBGTKUI_PRINT_DIALOG_GTK_H_

@@ -11,7 +11,7 @@
namespace libgtkui { namespace libgtkui {
// This class is just a switch between SettingsProviderGSettings and // This class is just a switch between SettingsProviderGSettings and
// SettingsProviderGtk3. Currently, it is empty and it's only purpose is so // SettingsProviderGtk. Currently, it is empty and it's only purpose is so
// that GtkUi can store just a std::unique_ptr<SettingsProvider> and not have to // that GtkUi can store just a std::unique_ptr<SettingsProvider> and not have to
// have the two impls each guarded by their own macros. // have the two impls each guarded by their own macros.
class SettingsProvider { class SettingsProvider {
@@ -20,7 +20,7 @@ class SettingsProvider {
protected: protected:
// Even though this class is not pure virtual, it should not be instantiated // Even though this class is not pure virtual, it should not be instantiated
// directly. Use SettingsProviderGSettings or SettingsProviderGtk3 instead. // directly. Use SettingsProviderGSettings or SettingsProviderGtk instead.
SettingsProvider() {} SettingsProvider() {}
}; };

@@ -35,10 +35,10 @@ SettingsProviderGSettings::SettingsProviderGSettings(GtkUi* delegate)
: delegate_(delegate) { : delegate_(delegate) {
DCHECK(delegate_); DCHECK(delegate_);
// Of all the supported distros, this code path should only be used by // Of all the supported distros, this code path should only be used by Ubuntu
// Ubuntu 14.04 (all the others have a sufficent gtk version to use the // 14.04 (all the others have a sufficient gtk version to use the GTK API).
// gtk3 API). The default in 14.04 is Unity, but Cinnamon has enough // The default in 14.04 is Unity, but Cinnamon has enough usage to justify
// usage to justify also checking its value. // also checking its value.
std::unique_ptr<base::Environment> env(base::Environment::Create()); std::unique_ptr<base::Environment> env(base::Environment::Create());
const gchar* settings_schema = base::nix::GetDesktopEnvironment(env.get()) == const gchar* settings_schema = base::nix::GetDesktopEnvironment(env.get()) ==
base::nix::DESKTOP_ENVIRONMENT_CINNAMON base::nix::DESKTOP_ENVIRONMENT_CINNAMON

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/ui/libgtkui/settings_provider_gtk3.h" #include "chrome/browser/ui/libgtkui/settings_provider_gtk.h"
#include "base/strings/string_split.h" #include "base/strings/string_split.h"
#include "chrome/browser/ui/libgtkui/gtk_ui.h" #include "chrome/browser/ui/libgtkui/gtk_ui.h"
@@ -57,8 +57,8 @@ void ParseActionString(const std::string& value,
} // namespace } // namespace
SettingsProviderGtk3::FrameActionSettingWatcher::FrameActionSettingWatcher( SettingsProviderGtk::FrameActionSettingWatcher::FrameActionSettingWatcher(
SettingsProviderGtk3* settings_provider, SettingsProviderGtk* settings_provider,
const std::string& setting_name, const std::string& setting_name,
views::LinuxUI::NonClientWindowFrameActionSourceType action_type, views::LinuxUI::NonClientWindowFrameActionSourceType action_type,
views::LinuxUI::NonClientWindowFrameAction default_action) views::LinuxUI::NonClientWindowFrameAction default_action)
@@ -74,12 +74,12 @@ SettingsProviderGtk3::FrameActionSettingWatcher::FrameActionSettingWatcher(
OnSettingChanged(settings, nullptr); OnSettingChanged(settings, nullptr);
} }
SettingsProviderGtk3::FrameActionSettingWatcher::~FrameActionSettingWatcher() { SettingsProviderGtk::FrameActionSettingWatcher::~FrameActionSettingWatcher() {
if (signal_id_) if (signal_id_)
g_signal_handler_disconnect(gtk_settings_get_default(), signal_id_); g_signal_handler_disconnect(gtk_settings_get_default(), signal_id_);
} }
void SettingsProviderGtk3::FrameActionSettingWatcher::OnSettingChanged( void SettingsProviderGtk::FrameActionSettingWatcher::OnSettingChanged(
GtkSettings* settings, GtkSettings* settings,
GParamSpec* param) { GParamSpec* param) {
std::string value = std::string value =
@@ -90,7 +90,7 @@ void SettingsProviderGtk3::FrameActionSettingWatcher::OnSettingChanged(
action); action);
} }
SettingsProviderGtk3::SettingsProviderGtk3(GtkUi* delegate) SettingsProviderGtk::SettingsProviderGtk(GtkUi* delegate)
: delegate_(delegate), signal_id_decoration_layout_(0) { : delegate_(delegate), signal_id_decoration_layout_(0) {
DCHECK(delegate_); DCHECK(delegate_);
GtkSettings* settings = gtk_settings_get_default(); GtkSettings* settings = gtk_settings_get_default();
@@ -128,14 +128,14 @@ SettingsProviderGtk3::SettingsProviderGtk3(GtkUi* delegate)
} }
} }
SettingsProviderGtk3::~SettingsProviderGtk3() { SettingsProviderGtk::~SettingsProviderGtk() {
if (signal_id_decoration_layout_) { if (signal_id_decoration_layout_) {
g_signal_handler_disconnect(gtk_settings_get_default(), g_signal_handler_disconnect(gtk_settings_get_default(),
signal_id_decoration_layout_); signal_id_decoration_layout_);
} }
} }
void SettingsProviderGtk3::SetWindowButtonOrderingFromGtkLayout( void SettingsProviderGtk::SetWindowButtonOrderingFromGtkLayout(
const std::string& gtk_layout) { const std::string& gtk_layout) {
std::vector<views::FrameButton> leading_buttons; std::vector<views::FrameButton> leading_buttons;
std::vector<views::FrameButton> trailing_buttons; std::vector<views::FrameButton> trailing_buttons;
@@ -143,15 +143,14 @@ void SettingsProviderGtk3::SetWindowButtonOrderingFromGtkLayout(
delegate_->SetWindowButtonOrdering(leading_buttons, trailing_buttons); delegate_->SetWindowButtonOrdering(leading_buttons, trailing_buttons);
} }
void SettingsProviderGtk3::OnDecorationButtonLayoutChanged( void SettingsProviderGtk::OnDecorationButtonLayoutChanged(GtkSettings* settings,
GtkSettings* settings, GParamSpec* param) {
GParamSpec* param) {
SetWindowButtonOrderingFromGtkLayout( SetWindowButtonOrderingFromGtkLayout(
GetGtkSettingsStringProperty(settings, "gtk-decoration-layout")); GetGtkSettingsStringProperty(settings, "gtk-decoration-layout"));
} }
void SettingsProviderGtk3::OnThemeChanged(GtkSettings* settings, void SettingsProviderGtk::OnThemeChanged(GtkSettings* settings,
GParamSpec* param) { GParamSpec* param) {
std::string layout = GetDecorationLayoutFromGtkWindow(); std::string layout = GetDecorationLayoutFromGtkWindow();
SetWindowButtonOrderingFromGtkLayout(layout); SetWindowButtonOrderingFromGtkLayout(layout);
} }

@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_LIBGTKUI_SETTINGS_PROVIDER_GTK3_H_ #ifndef CHROME_BROWSER_UI_LIBGTKUI_SETTINGS_PROVIDER_GTK_H_
#define CHROME_BROWSER_UI_LIBGTKUI_SETTINGS_PROVIDER_GTK3_H_ #define CHROME_BROWSER_UI_LIBGTKUI_SETTINGS_PROVIDER_GTK_H_
#include <string> #include <string>
@@ -19,16 +19,16 @@ namespace libgtkui {
class GtkUi; class GtkUi;
class SettingsProviderGtk3 : public SettingsProvider { class SettingsProviderGtk : public SettingsProvider {
public: public:
explicit SettingsProviderGtk3(GtkUi* delegate); explicit SettingsProviderGtk(GtkUi* delegate);
~SettingsProviderGtk3() override; ~SettingsProviderGtk() override;
private: private:
class FrameActionSettingWatcher { class FrameActionSettingWatcher {
public: public:
FrameActionSettingWatcher( FrameActionSettingWatcher(
SettingsProviderGtk3* settings_provider, SettingsProviderGtk* settings_provider,
const std::string& setting_name, const std::string& setting_name,
views::LinuxUI::NonClientWindowFrameActionSourceType action_type, views::LinuxUI::NonClientWindowFrameActionSourceType action_type,
views::LinuxUI::NonClientWindowFrameAction default_action); views::LinuxUI::NonClientWindowFrameAction default_action);
@@ -41,7 +41,7 @@ class SettingsProviderGtk3 : public SettingsProvider {
GParamSpec*); GParamSpec*);
private: private:
SettingsProviderGtk3* settings_provider_; SettingsProviderGtk* settings_provider_;
std::string setting_name_; std::string setting_name_;
views::LinuxUI::NonClientWindowFrameActionSourceType action_type_; views::LinuxUI::NonClientWindowFrameActionSourceType action_type_;
views::LinuxUI::NonClientWindowFrameAction default_action_; views::LinuxUI::NonClientWindowFrameAction default_action_;
@@ -52,13 +52,13 @@ class SettingsProviderGtk3 : public SettingsProvider {
void SetWindowButtonOrderingFromGtkLayout(const std::string& gtk_layout); void SetWindowButtonOrderingFromGtkLayout(const std::string& gtk_layout);
CHROMEG_CALLBACK_1(SettingsProviderGtk3, CHROMEG_CALLBACK_1(SettingsProviderGtk,
void, void,
OnDecorationButtonLayoutChanged, OnDecorationButtonLayoutChanged,
GtkSettings*, GtkSettings*,
GParamSpec*); GParamSpec*);
CHROMEG_CALLBACK_1(SettingsProviderGtk3, CHROMEG_CALLBACK_1(SettingsProviderGtk,
void, void,
OnThemeChanged, OnThemeChanged,
GtkSettings*, GtkSettings*,
@@ -71,9 +71,9 @@ class SettingsProviderGtk3 : public SettingsProvider {
std::vector<std::unique_ptr<FrameActionSettingWatcher>> std::vector<std::unique_ptr<FrameActionSettingWatcher>>
frame_action_setting_watchers_; frame_action_setting_watchers_;
DISALLOW_COPY_AND_ASSIGN(SettingsProviderGtk3); DISALLOW_COPY_AND_ASSIGN(SettingsProviderGtk);
}; };
} // namespace libgtkui } // namespace libgtkui
#endif // CHROME_BROWSER_UI_LIBGTKUI_SETTINGS_PROVIDER_GTK3_H_ #endif // CHROME_BROWSER_UI_LIBGTKUI_SETTINGS_PROVIDER_GTK_H_

@@ -24,7 +24,7 @@
namespace libgtkui { namespace libgtkui {
X11InputMethodContextImplGtk2::X11InputMethodContextImplGtk2( X11InputMethodContextImplGtk::X11InputMethodContextImplGtk(
ui::LinuxInputMethodContextDelegate* delegate, ui::LinuxInputMethodContextDelegate* delegate,
bool is_simple) bool is_simple)
: delegate_(delegate), : delegate_(delegate),
@@ -49,7 +49,7 @@ X11InputMethodContextImplGtk2::X11InputMethodContextImplGtk2(
// handled. // handled.
} }
X11InputMethodContextImplGtk2::~X11InputMethodContextImplGtk2() { X11InputMethodContextImplGtk::~X11InputMethodContextImplGtk() {
if (gtk_context_) { if (gtk_context_) {
g_object_unref(gtk_context_); g_object_unref(gtk_context_);
gtk_context_ = nullptr; gtk_context_ = nullptr;
@@ -58,7 +58,7 @@ X11InputMethodContextImplGtk2::~X11InputMethodContextImplGtk2() {
// Overriden from ui::LinuxInputMethodContext // Overriden from ui::LinuxInputMethodContext
bool X11InputMethodContextImplGtk2::DispatchKeyEvent( bool X11InputMethodContextImplGtk::DispatchKeyEvent(
const ui::KeyEvent& key_event) { const ui::KeyEvent& key_event) {
if (!key_event.HasNativeEvent() || !gtk_context_) if (!key_event.HasNativeEvent() || !gtk_context_)
return false; return false;
@@ -92,19 +92,19 @@ bool X11InputMethodContextImplGtk2::DispatchKeyEvent(
return handled; return handled;
} }
void X11InputMethodContextImplGtk2::Reset() { void X11InputMethodContextImplGtk::Reset() {
gtk_im_context_reset(gtk_context_); gtk_im_context_reset(gtk_context_);
} }
void X11InputMethodContextImplGtk2::Focus() { void X11InputMethodContextImplGtk::Focus() {
gtk_im_context_focus_in(gtk_context_); gtk_im_context_focus_in(gtk_context_);
} }
void X11InputMethodContextImplGtk2::Blur() { void X11InputMethodContextImplGtk::Blur() {
gtk_im_context_focus_out(gtk_context_); gtk_im_context_focus_out(gtk_context_);
} }
void X11InputMethodContextImplGtk2::SetCursorLocation(const gfx::Rect& rect) { void X11InputMethodContextImplGtk::SetCursorLocation(const gfx::Rect& rect) {
// Remember the caret bounds so that we can set the cursor location later. // Remember the caret bounds so that we can set the cursor location later.
// gtk_im_context_set_cursor_location() takes the location relative to the // gtk_im_context_set_cursor_location() takes the location relative to the
// client window, which is unknown at this point. So we'll call // client window, which is unknown at this point. So we'll call
@@ -120,7 +120,7 @@ void X11InputMethodContextImplGtk2::SetCursorLocation(const gfx::Rect& rect) {
// private: // private:
void X11InputMethodContextImplGtk2::ResetXModifierKeycodesCache() { void X11InputMethodContextImplGtk::ResetXModifierKeycodesCache() {
modifier_keycodes_.clear(); modifier_keycodes_.clear();
meta_keycodes_.clear(); meta_keycodes_.clear();
super_keycodes_.clear(); super_keycodes_.clear();
@@ -164,7 +164,7 @@ void X11InputMethodContextImplGtk2::ResetXModifierKeycodesCache() {
} }
} }
GdkEvent* X11InputMethodContextImplGtk2::GdkEventFromNativeEvent( GdkEvent* X11InputMethodContextImplGtk::GdkEventFromNativeEvent(
const ui::PlatformEvent& native_event) { const ui::PlatformEvent& native_event) {
XEvent xkeyevent; XEvent xkeyevent;
if (native_event->type == GenericEvent) { if (native_event->type == GenericEvent) {
@@ -256,12 +256,12 @@ GdkEvent* X11InputMethodContextImplGtk2::GdkEventFromNativeEvent(
return event; return event;
} }
bool X11InputMethodContextImplGtk2::IsKeycodeModifierKey( bool X11InputMethodContextImplGtk::IsKeycodeModifierKey(
unsigned int keycode) const { unsigned int keycode) const {
return modifier_keycodes_.find(keycode) != modifier_keycodes_.end(); return modifier_keycodes_.find(keycode) != modifier_keycodes_.end();
} }
bool X11InputMethodContextImplGtk2::IsAnyOfKeycodesPressed( bool X11InputMethodContextImplGtk::IsAnyOfKeycodesPressed(
const std::vector<int>& keycodes, const std::vector<int>& keycodes,
const char* keybits, const char* keybits,
int num_keys) const { int num_keys) const {
@@ -277,15 +277,15 @@ bool X11InputMethodContextImplGtk2::IsAnyOfKeycodesPressed(
// GtkIMContext event handlers. // GtkIMContext event handlers.
void X11InputMethodContextImplGtk2::OnCommit(GtkIMContext* context, void X11InputMethodContextImplGtk::OnCommit(GtkIMContext* context,
gchar* text) { gchar* text) {
if (context != gtk_context_) if (context != gtk_context_)
return; return;
delegate_->OnCommit(base::UTF8ToUTF16(text)); delegate_->OnCommit(base::UTF8ToUTF16(text));
} }
void X11InputMethodContextImplGtk2::OnPreeditChanged(GtkIMContext* context) { void X11InputMethodContextImplGtk::OnPreeditChanged(GtkIMContext* context) {
if (context != gtk_context_) if (context != gtk_context_)
return; return;
@@ -302,14 +302,14 @@ void X11InputMethodContextImplGtk2::OnPreeditChanged(GtkIMContext* context) {
delegate_->OnPreeditChanged(composition_text); delegate_->OnPreeditChanged(composition_text);
} }
void X11InputMethodContextImplGtk2::OnPreeditEnd(GtkIMContext* context) { void X11InputMethodContextImplGtk::OnPreeditEnd(GtkIMContext* context) {
if (context != gtk_context_) if (context != gtk_context_)
return; return;
delegate_->OnPreeditEnd(); delegate_->OnPreeditEnd();
} }
void X11InputMethodContextImplGtk2::OnPreeditStart(GtkIMContext* context) { void X11InputMethodContextImplGtk::OnPreeditStart(GtkIMContext* context) {
if (context != gtk_context_) if (context != gtk_context_)
return; return;

@@ -23,11 +23,11 @@ namespace libgtkui {
// An implementation of LinuxInputMethodContext which is based on X11 event loop // An implementation of LinuxInputMethodContext which is based on X11 event loop
// and uses GtkIMContext(gtk-immodule) as a bridge from/to underlying IMEs. // and uses GtkIMContext(gtk-immodule) as a bridge from/to underlying IMEs.
class X11InputMethodContextImplGtk2 : public ui::LinuxInputMethodContext { class X11InputMethodContextImplGtk : public ui::LinuxInputMethodContext {
public: public:
X11InputMethodContextImplGtk2(ui::LinuxInputMethodContextDelegate* delegate, X11InputMethodContextImplGtk(ui::LinuxInputMethodContextDelegate* delegate,
bool is_simple); bool is_simple);
~X11InputMethodContextImplGtk2() override; ~X11InputMethodContextImplGtk() override;
// Overriden from ui::LinuxInputMethodContext // Overriden from ui::LinuxInputMethodContext
bool DispatchKeyEvent(const ui::KeyEvent& key_event) override; bool DispatchKeyEvent(const ui::KeyEvent& key_event) override;
@@ -58,20 +58,20 @@ class X11InputMethodContextImplGtk2 : public ui::LinuxInputMethodContext {
// GtkIMContext event handlers. They are shared among |gtk_context_simple_| // GtkIMContext event handlers. They are shared among |gtk_context_simple_|
// and |gtk_multicontext_|. // and |gtk_multicontext_|.
CHROMEG_CALLBACK_1(X11InputMethodContextImplGtk2, CHROMEG_CALLBACK_1(X11InputMethodContextImplGtk,
void, void,
OnCommit, OnCommit,
GtkIMContext*, GtkIMContext*,
gchar*); gchar*);
CHROMEG_CALLBACK_0(X11InputMethodContextImplGtk2, CHROMEG_CALLBACK_0(X11InputMethodContextImplGtk,
void, void,
OnPreeditChanged, OnPreeditChanged,
GtkIMContext*); GtkIMContext*);
CHROMEG_CALLBACK_0(X11InputMethodContextImplGtk2, CHROMEG_CALLBACK_0(X11InputMethodContextImplGtk,
void, void,
OnPreeditEnd, OnPreeditEnd,
GtkIMContext*); GtkIMContext*);
CHROMEG_CALLBACK_0(X11InputMethodContextImplGtk2, CHROMEG_CALLBACK_0(X11InputMethodContextImplGtk,
void, void,
OnPreeditStart, OnPreeditStart,
GtkIMContext*); GtkIMContext*);
@@ -95,7 +95,7 @@ class X11InputMethodContextImplGtk2 : public ui::LinuxInputMethodContext {
std::vector<int> super_keycodes_; std::vector<int> super_keycodes_;
std::vector<int> hyper_keycodes_; std::vector<int> hyper_keycodes_;
DISALLOW_COPY_AND_ASSIGN(X11InputMethodContextImplGtk2); DISALLOW_COPY_AND_ASSIGN(X11InputMethodContextImplGtk);
}; };
} // namespace libgtkui } // namespace libgtkui

@@ -67,10 +67,9 @@ ChromeBrowserMainExtraPartsViewsLinux::
} }
void ChromeBrowserMainExtraPartsViewsLinux::PreEarlyInitialization() { void ChromeBrowserMainExtraPartsViewsLinux::PreEarlyInitialization() {
// TODO(erg): Refactor this into a dlopen call when we add a GTK3 port. views::LinuxUI* gtk_ui = BuildGtkUi();
views::LinuxUI* gtk2_ui = BuildGtkUi(); gtk_ui->SetNativeThemeOverride(base::Bind(&GetNativeThemeForWindow));
gtk2_ui->SetNativeThemeOverride(base::Bind(&GetNativeThemeForWindow)); views::LinuxUI::SetInstance(gtk_ui);
views::LinuxUI::SetInstance(gtk2_ui);
} }
void ChromeBrowserMainExtraPartsViewsLinux::ToolkitInitialized() { void ChromeBrowserMainExtraPartsViewsLinux::ToolkitInitialized() {

@@ -7,7 +7,6 @@ import("//build/config/chromecast_build.gni")
import("//build/config/compiler/compiler.gni") import("//build/config/compiler/compiler.gni")
import("//build/config/dcheck_always_on.gni") import("//build/config/dcheck_always_on.gni")
import("//build/config/features.gni") import("//build/config/features.gni")
import("//build/config/linux/gtk/gtk.gni")
import("//device/vr/buildflags/buildflags.gni") import("//device/vr/buildflags/buildflags.gni")
import("//extensions/buildflags/buildflags.gni") import("//extensions/buildflags/buildflags.gni")
import("//media/media_options.gni") import("//media/media_options.gni")

@@ -340,7 +340,7 @@ Instead of running `install-build-deps.sh` to install build dependencies, run:
```shell ```shell
$ sudo pacman -S --needed python perl gcc gcc-libs bison flex gperf pkgconfig \ $ sudo pacman -S --needed python perl gcc gcc-libs bison flex gperf pkgconfig \
nss alsa-lib glib2 gtk2 nspr ttf-ms-fonts freetype2 cairo dbus libgnome-keyring nss alsa-lib glib2 gtk3 nspr ttf-ms-fonts freetype2 cairo dbus libgnome-keyring
``` ```
For the optional packages on Arch Linux: For the optional packages on Arch Linux:
@@ -389,7 +389,7 @@ Instead of running `build/install-build-deps.sh`, run:
su -c 'yum install git python bzip2 tar pkgconfig atk-devel alsa-lib-devel \ su -c 'yum install git python bzip2 tar pkgconfig atk-devel alsa-lib-devel \
bison binutils brlapi-devel bluez-libs-devel bzip2-devel cairo-devel \ bison binutils brlapi-devel bluez-libs-devel bzip2-devel cairo-devel \
cups-devel dbus-devel dbus-glib-devel expat-devel fontconfig-devel \ cups-devel dbus-devel dbus-glib-devel expat-devel fontconfig-devel \
freetype-devel gcc-c++ glib2-devel glibc.i686 gperf glib2-devel gtk2-devel \ freetype-devel gcc-c++ glib2-devel glibc.i686 gperf glib2-devel \
gtk3-devel java-1.*.0-openjdk-devel libatomic libcap-devel libffi-devel \ gtk3-devel java-1.*.0-openjdk-devel libatomic libcap-devel libffi-devel \
libgcc.i686 libgnome-keyring-devel libjpeg-devel libstdc++.i686 libX11-devel \ libgcc.i686 libgnome-keyring-devel libjpeg-devel libstdc++.i686 libX11-devel \
libXScrnSaver-devel libXtst-devel libxkbcommon-x11-devel ncurses-compat-libs \ libXScrnSaver-devel libXtst-devel libxkbcommon-x11-devel ncurses-compat-libs \
@@ -423,8 +423,7 @@ sudo zypper in subversion pkg-config python perl bison flex gperf \
``` ```
For 11.0, use `libnspr4-0d` and `libnspr4-dev` instead of `mozilla-nspr` and For 11.0, use `libnspr4-0d` and `libnspr4-dev` instead of `mozilla-nspr` and
`mozilla-nspr-devel`, and use `php5-cgi` instead of `php5-fastcgi`. And need `mozilla-nspr-devel`, and use `php5-cgi` instead of `php5-fastcgi`.
`gtk2-devel`.
(openSUSE 11.0) (openSUSE 11.0)
@@ -432,7 +431,7 @@ For 11.0, use `libnspr4-0d` and `libnspr4-dev` instead of `mozilla-nspr` and
sudo zypper in subversion pkg-config python perl \ sudo zypper in subversion pkg-config python perl \
bison flex gperf mozilla-nss-devel glib2-devel gtk-devel \ bison flex gperf mozilla-nss-devel glib2-devel gtk-devel \
libnspr4-0d libnspr4-dev wdiff lighttpd gcc gcc-c++ libexpat-devel \ libnspr4-0d libnspr4-dev wdiff lighttpd gcc gcc-c++ libexpat-devel \
php5-cgi alsa-devel gtk2-devel jpeg-devel php5-cgi alsa-devel gtk3-devel jpeg-devel
``` ```
The Ubuntu package `sun-java6-fonts` contains a subset of Java of the fonts used. The Ubuntu package `sun-java6-fonts` contains a subset of Java of the fonts used.

@@ -453,7 +453,7 @@ Here's how to install the Arabic (ar) and Hebrew (he) language packs:
Note that the `--lang` flag does **not** work properly for this. Note that the `--lang` flag does **not** work properly for this.
On non-Debian systems, you need the `gtk20.mo` files. (Please update these docs On non-Debian systems, you need the `gtk30.mo` files. (Please update these docs
with the appropriate instructions if you know what they are.) with the appropriate instructions if you know what they are.)
## Breakpad ## Breakpad

@@ -8,7 +8,7 @@ for notes on how to make GTK warnings fatal.
## Using GTK Debug packages ## Using GTK Debug packages
sudo apt-get install libgtk2.0-0-dbg sudo apt-get install libgtk-3-0-dbg
Make sure that you're building a binary that matches your architecture (e.g. Make sure that you're building a binary that matches your architecture (e.g.
64-bit on a 64-bit machine), and there you go. 64-bit on a 64-bit machine), and there you go.
@@ -21,7 +21,7 @@ doing:
```shell ```shell
$ cd /my/dir $ cd /my/dir
$ apt-get source libgtk2.0-0 $ apt-get source libgtk-3-0
$ gdb ... $ gdb ...
(gdb) set substitute-path /build/buildd /my/dir (gdb) set substitute-path /build/buildd /my/dir
``` ```
@@ -46,14 +46,6 @@ And then run Chrome with
GTK_MODULES=gtkparasite ./out/Debug/chrome GTK_MODULES=gtkparasite ./out/Debug/chrome
### ghardy
If you're within the Google network on ghardy, which is too old to include
gtkparasite, you can do:
scp bunny.sfo:/usr/lib/gtk-2.0/modules/libgtkparasite.so /tmp
sudo cp /tmp/libgtkparasite.so /usr/lib/gtk-2.0/modules/libgtkparasite.so
## GDK_DEBUG ## GDK_DEBUG
Use `GDK_DEBUG=nograbs` to run GTK+ without grabs. This is useful for gdb Use `GDK_DEBUG=nograbs` to run GTK+ without grabs. This is useful for gdb

@@ -49,4 +49,4 @@ For GTK3.20 or later, themes will as usual have to replace ".entry" with
"entry". "entry".
The list of CSS selectors that Chromium uses to determine its colors is in The list of CSS selectors that Chromium uses to determine its colors is in
//src/chrome/browser/ui/libgtkui/native_theme_gtk3.cc. //src/chrome/browser/ui/libgtkui/native_theme_gtk.cc.

@@ -71,14 +71,10 @@ void ContinueWindowGtk::CreateWindow() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!continue_window_); DCHECK(!continue_window_);
GtkDialogFlags flags = GTK_DIALOG_MODAL;
#if GTK_MAJOR_VERSION == 2
flags = static_cast<GtkDialogFlags>(flags | GTK_DIALOG_NO_SEPARATOR);
#endif
continue_window_ = gtk_dialog_new_with_buttons( continue_window_ = gtk_dialog_new_with_buttons(
l10n_util::GetStringUTF8(IDS_PRODUCT_NAME).c_str(), l10n_util::GetStringUTF8(IDS_PRODUCT_NAME).c_str(),
nullptr, nullptr,
flags, GTK_DIALOG_MODAL,
l10n_util::GetStringUTF8(IDS_STOP_SHARING_BUTTON).c_str(), l10n_util::GetStringUTF8(IDS_STOP_SHARING_BUTTON).c_str(),
GTK_RESPONSE_CANCEL, GTK_RESPONSE_CANCEL,
l10n_util::GetStringUTF8(IDS_CONTINUE_BUTTON).c_str(), l10n_util::GetStringUTF8(IDS_CONTINUE_BUTTON).c_str(),

@@ -213,12 +213,8 @@ void DisconnectWindowGtk::Start(
G_GNUC_END_IGNORE_DEPRECATIONS; G_GNUC_END_IGNORE_DEPRECATIONS;
gtk_container_add(GTK_CONTAINER(window), align); gtk_container_add(GTK_CONTAINER(window), align);
#if GTK_MAJOR_VERSION == 2
GtkWidget* button_row = gtk_hbox_new(FALSE, 12);
#else
GtkWidget* button_row = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); GtkWidget* button_row = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
gtk_box_set_homogeneous(GTK_BOX(button_row), FALSE); gtk_box_set_homogeneous(GTK_BOX(button_row), FALSE);
#endif
gtk_container_add(GTK_CONTAINER(align), button_row); gtk_container_add(GTK_CONTAINER(align), button_row);
button_ = gtk_button_new_with_label( button_ = gtk_button_new_with_label(
@@ -238,13 +234,11 @@ void DisconnectWindowGtk::Start(
gtk_label_set_attributes(GTK_LABEL(message_), attributes); gtk_label_set_attributes(GTK_LABEL(message_), attributes);
pango_attr_list_unref(attributes); pango_attr_list_unref(attributes);
#if GTK_MAJOR_VERSION > 2
GdkScreen* screen = gtk_widget_get_screen(disconnect_window_); GdkScreen* screen = gtk_widget_get_screen(disconnect_window_);
GdkVisual* visual = gdk_screen_get_rgba_visual(screen); GdkVisual* visual = gdk_screen_get_rgba_visual(screen);
if (visual) if (visual)
gtk_widget_set_visual(disconnect_window_, visual); gtk_widget_set_visual(disconnect_window_, visual);
#endif
gtk_widget_show_all(disconnect_window_); gtk_widget_show_all(disconnect_window_);
@@ -287,51 +281,10 @@ gboolean DisconnectWindowGtk::OnConfigure(GtkWidget* widget,
// gdk_window_set_back_pixmap() is not supported in GDK3, and // gdk_window_set_back_pixmap() is not supported in GDK3, and
// background drawing is handled in OnDraw(). // background drawing is handled in OnDraw().
#if GTK_MAJOR_VERSION == 2
// Create the depth 1 pixmap for the window shape.
GdkPixmap* shape_mask =
gdk_pixmap_new(nullptr, current_width_, current_height_, 1);
cairo_t* cairo_context = gdk_cairo_create(shape_mask);
// Set the arc radius for the corners.
const int kCornerRadius = 6;
// Initialize the whole bitmap to be transparent.
cairo_set_source_rgba(cairo_context, 0, 0, 0, 0);
cairo_set_operator(cairo_context, CAIRO_OPERATOR_SOURCE);
cairo_paint(cairo_context);
// Paint an opaque round rect covering the whole area (leaving the extreme
// corners transparent).
cairo_set_source_rgba(cairo_context, 1, 1, 1, 1);
cairo_set_operator(cairo_context, CAIRO_OPERATOR_SOURCE);
AddRoundRectPath(cairo_context, current_width_, current_height_,
kCornerRadius);
cairo_fill(cairo_context);
cairo_destroy(cairo_context);
gdk_window_shape_combine_mask(widget->window, shape_mask, 0, 0);
g_object_unref(shape_mask);
// Create a full-color pixmap for the window background image.
GdkPixmap* background =
gdk_pixmap_new(nullptr, current_width_, current_height_, 24);
cairo_context = gdk_cairo_create(background);
DrawBackground(cairo_context, current_width_, current_height_);
cairo_destroy(cairo_context);
gdk_window_set_back_pixmap(widget->window, background, FALSE);
g_object_unref(background);
gdk_window_invalidate_rect(widget->window, nullptr, TRUE);
#endif // GTK_MAJOR_VERSION == 2
return FALSE; return FALSE;
} }
gboolean DisconnectWindowGtk::OnDraw(GtkWidget* widget, cairo_t* cr) { gboolean DisconnectWindowGtk::OnDraw(GtkWidget* widget, cairo_t* cr) {
#if GTK_MAJOR_VERSION == 2
NOTREACHED();
#endif
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DrawBackground(cr, current_width_, current_height_); DrawBackground(cr, current_width_, current_height_);

@@ -85,8 +85,9 @@ if (prebuilt_instrumented_libraries_available) {
# DSOs before system-installed versions in library search path. # DSOs before system-installed versions in library search path.
"-Wl,-R,\$ORIGIN/instrumented_libraries_prebuilt/$sanitizer_type/lib", "-Wl,-R,\$ORIGIN/instrumented_libraries_prebuilt/$sanitizer_type/lib",
"-Wl,-z,origin", "-Wl,-z,origin",
# Add some padding to allow RPATHs to be modified later. # Add some padding to allow RPATHs to be modified later.
"-Wl,-R,________________________________________________________________PADDING________________________________________________________________" "-Wl,-R,________________________________________________________________PADDING________________________________________________________________",
] ]
} }
} }
@@ -122,7 +123,6 @@ if (use_locally_built_instrumented_libraries) {
":libgnome-keyring0", ":libgnome-keyring0",
":libgpg-error0", ":libgpg-error0",
":libgtk-3-0", ":libgtk-3-0",
":libgtk2.0-0",
":libido3-0.1-0", ":libido3-0.1-0",
":libindicator3-7", ":libindicator3-7",
":libnspr4", ":libnspr4",
@@ -175,8 +175,9 @@ if (use_locally_built_instrumented_libraries) {
# DSOs before system-installed versions in library search path. # DSOs before system-installed versions in library search path.
"-Wl,-R,\$ORIGIN/instrumented_libraries/${sanitizer_type}/lib", "-Wl,-R,\$ORIGIN/instrumented_libraries/${sanitizer_type}/lib",
"-Wl,-z,origin", "-Wl,-z,origin",
# Add some padding to allow RPATHs to be modified later. # Add some padding to allow RPATHs to be modified later.
"-Wl,-R,________________________________________________________________PADDING________________________________________________________________" "-Wl,-R,________________________________________________________________PADDING________________________________________________________________",
] ]
} }
@@ -559,22 +560,6 @@ if (use_locally_built_instrumented_libraries) {
extra_configure_flags = [ "--disable-static" ] extra_configure_flags = [ "--disable-static" ]
} }
instrumented_library("libgtk2.0-0") {
package_cflags = [ "-Wno-return-type" ]
extra_configure_flags = [
"--disable-static",
# From debian/rules.
"--prefix=/usr",
"--sysconfdir=/etc",
"--enable-test-print-backend",
"--enable-introspection=no",
"--with-xinput=yes",
]
patch = "patches/libgtk2.0-0.${instrumented_libraries_platform}.diff"
pre_build = "scripts/pre-build/libgtk2.0-0.sh"
}
instrumented_library("libgtk-3-0") { instrumented_library("libgtk-3-0") {
package_cflags = [ "-Wno-return-type" ] package_cflags = [ "-Wno-return-type" ]
extra_configure_flags = [ extra_configure_flags = [

@@ -1,15 +0,0 @@
diff -rupN ./gtk/gtkmenushell.h ../gtk+2.0-2.24.23-patched/gtk/gtkmenushell.h
--- ./gtk/gtkmenushell.h 2014-03-06 08:56:42.000000000 +0400
+++ ../gtk+2.0-2.24.23-patched/gtk/gtkmenushell.h 2014-09-30 23:37:46.908364552 +0400
@@ -136,6 +136,11 @@ void _gtk_menu_shell_set_keyboard_mo
gboolean keyboard_mode);
gboolean _gtk_menu_shell_get_keyboard_mode (GtkMenuShell *menu_shell);
+// https://bugs.launchpad.net/bugs/945135
+gboolean ubuntu_gtk_menu_shell_activate_mnemonic (GtkMenuShell *shell,
+ GtkWidget *item);
+gboolean ubuntu_gtk_menu_shell_activate_first (GtkMenuShell *menu_shell,
+ gboolean search_sensitive);
G_END_DECLS
#endif /* __GTK_MENU_SHELL_H__ */

@@ -37,7 +37,6 @@ libglib2.0-0 \
libgnome-keyring0 \ libgnome-keyring0 \
libgpg-error0 \ libgpg-error0 \
libgtk-3-0 \ libgtk-3-0 \
libgtk2.0-0 \
libido3-0.1-0 \ libido3-0.1-0 \
libindicator3-7 \ libindicator3-7 \
libnspr4 \ libnspr4 \

@@ -1,13 +0,0 @@
#!/bin/bash
# Copyright 2014 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.
# This script does some preparations before build of instrumented libgtk2.0-0.
# Use the system-installed gtk-update-icon-cache during building. Normally a
# just-built one is used, however in MSan builds it will crash due to
# uninstrumented dependencies.
sed -i "s|./gtk-update-icon-cache|/usr/bin/gtk-update-icon-cache|g" gtk/Makefile.am
autoreconf

@@ -30,7 +30,7 @@ apt-get install -yq libffi-dev libssl-dev
# Chrome dependencies # Chrome dependencies
apt-get install -yq libpangocairo-1.0-0 libXcomposite1 libXcursor1 libXdamage1 \ apt-get install -yq libpangocairo-1.0-0 libXcomposite1 libXcursor1 libXdamage1 \
libXi6 libXtst6 libnss3 libcups2 libgconf2-4 libXss1 libXrandr2 \ libXi6 libXtst6 libnss3 libcups2 libgconf2-4 libXss1 libXrandr2 \
libatk1.0-0 libasound2 libgtk2.0-0 libatk1.0-0 libasound2 libgtk-3-0
# Trace collection dependencies # Trace collection dependencies
apt-get install -yq xvfb apt-get install -yq xvfb

@@ -2,7 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
import("//build/config/linux/gtk/gtk.gni")
import("//build/config/linux/pkg_config.gni") import("//build/config/linux/pkg_config.gni")
import("//build/config/features.gni") import("//build/config/features.gni")
import("//build/config/ui.gni") import("//build/config/ui.gni")
@@ -127,6 +126,7 @@ component("accessibility") {
sources += [ sources += [
"platform/atk_util_auralinux.cc", "platform/atk_util_auralinux.cc",
"platform/atk_util_auralinux.h", "platform/atk_util_auralinux.h",
"platform/atk_util_auralinux_gtk.cc",
"platform/ax_platform_atk_hyperlink.cc", "platform/ax_platform_atk_hyperlink.cc",
"platform/ax_platform_atk_hyperlink.h", "platform/ax_platform_atk_hyperlink.h",
"platform/ax_platform_node_auralinux.cc", "platform/ax_platform_node_auralinux.cc",
@@ -138,11 +138,6 @@ component("accessibility") {
if (use_glib) { if (use_glib) {
configs += [ "//build/config/linux:glib" ] configs += [ "//build/config/linux:glib" ]
} }
if (use_gtk3) {
sources += [ "platform/atk_util_auralinux_gtk3.cc" ]
} else {
sources += [ "platform/atk_util_auralinux_gtk2.cc" ]
}
} }
if (use_aura) { if (use_aura) {

@@ -1,84 +0,0 @@
// Copyright 2017 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 <glib-2.0/gmodule.h>
#include "base/bind.h"
#include "base/environment.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/task/post_task.h"
#include "ui/accessibility/platform/atk_util_auralinux.h"
typedef void (*GnomeAccessibilityModuleInitFunc)();
const char kAtkBridgeModule[] = "atk-bridge";
const char kAtkBridgePath[] = "gtk-2.0/modules/libatk-bridge.so";
const char kAtkBridgeSymbolName[] = "gnome_accessibility_module_init";
const char kGtkModules[] = "GTK_MODULES";
namespace ui {
// Returns a function pointer to be invoked on the main thread to init
// the gnome accessibility module if it's enabled (nullptr otherwise).
GnomeAccessibilityModuleInitFunc GetAccessibilityModuleInitFunc() {
base::AssertBlockingAllowed();
// Try to load libatk-bridge.so.
base::FilePath atk_bridge_path(ATK_LIB_DIR);
atk_bridge_path = atk_bridge_path.Append(kAtkBridgePath);
GModule* bridge = g_module_open(atk_bridge_path.value().c_str(),
static_cast<GModuleFlags>(0));
if (!bridge) {
VLOG(1) << "Unable to open module " << atk_bridge_path.value();
return nullptr;
}
GnomeAccessibilityModuleInitFunc init_func = nullptr;
if (!g_module_symbol(bridge, kAtkBridgeSymbolName, (gpointer*)&init_func)) {
VLOG(1) << "Unable to get symbol pointer from " << atk_bridge_path.value();
return nullptr;
}
DCHECK(init_func);
return init_func;
}
void FinishAccessibilityInitOnMainThread(
GnomeAccessibilityModuleInitFunc init_func) {
if (!init_func) {
VLOG(1) << "Will not enable ATK accessibility support.";
return;
}
init_func();
}
bool AtkUtilAuraLinux::PlatformShouldEnableAccessibility() {
std::unique_ptr<base::Environment> env(base::Environment::Create());
std::string gtk_modules;
if (!env->GetVar(kGtkModules, &gtk_modules))
return false;
for (const std::string& module :
base::SplitString(gtk_modules, ":", base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY)) {
if (module == kAtkBridgeModule)
return true;
}
return false;
}
void AtkUtilAuraLinux::PlatformInitializeAsync() {
base::PostTaskWithTraitsAndReplyWithResult(
FROM_HERE,
{base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::Bind(&GetAccessibilityModuleInitFunc),
base::Bind(&FinishAccessibilityInitOnMainThread));
}
} // namespace ui

@@ -2,12 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
import("//build/config/linux/gtk/gtk.gni")
import("//build/config/ui.gni") import("//build/config/ui.gni")
declare_args() { declare_args() {
# Whether we should draw the minimize, maximize/restore, and close # Whether we should draw the minimize, maximize/restore, and close
# buttons using the system theme. Only used on Linux with GTK3. # buttons using the system theme. Only used on Linux.
enable_native_window_nav_buttons = enable_native_window_nav_buttons = use_aura && !use_ozone && is_desktop_linux
use_aura && !use_ozone && is_desktop_linux && use_gtk3
} }

@@ -57,11 +57,6 @@ class NavButtonProvider;
// Adapter class with targets to render like different toolkits. Set by any // Adapter class with targets to render like different toolkits. Set by any
// project that wants to do linux desktop native rendering. // project that wants to do linux desktop native rendering.
//
// TODO(erg): We're hardcoding GTK2, when we'll need to have backends for (at
// minimum) GTK2 and GTK3. LinuxUI::instance() should actually be a very
// complex method that pokes around with dlopen against a libuigtk2.so, a
// liuigtk3.so, etc.
class VIEWS_EXPORT LinuxUI : public ui::LinuxInputMethodContextFactory, class VIEWS_EXPORT LinuxUI : public ui::LinuxInputMethodContextFactory,
public gfx::LinuxFontDelegate, public gfx::LinuxFontDelegate,
public ui::ShellDialogLinux, public ui::ShellDialogLinux,