OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/libgtk2ui/gtk2_ui.h" | 5 #include "chrome/browser/ui/libgtk2ui/gtk2_ui.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 #include <pango/pango.h> | 8 #include <pango/pango.h> |
9 #include <X11/Xcursor/Xcursor.h> | 9 #include <X11/Xcursor/Xcursor.h> |
10 | |
11 #include <cmath> | |
10 #include <set> | 12 #include <set> |
11 #include <utility> | 13 #include <utility> |
12 | 14 |
13 #include "base/command_line.h" | 15 #include "base/command_line.h" |
14 #include "base/debug/leak_annotations.h" | 16 #include "base/debug/leak_annotations.h" |
15 #include "base/environment.h" | 17 #include "base/environment.h" |
16 #include "base/i18n/rtl.h" | 18 #include "base/i18n/rtl.h" |
17 #include "base/logging.h" | 19 #include "base/logging.h" |
18 #include "base/macros.h" | 20 #include "base/macros.h" |
19 #include "base/nix/mime_util_xdg.h" | 21 #include "base/nix/mime_util_xdg.h" |
20 #include "base/nix/xdg_util.h" | 22 #include "base/nix/xdg_util.h" |
21 #include "base/stl_util.h" | 23 #include "base/stl_util.h" |
22 #include "base/strings/string_split.h" | 24 #include "base/strings/string_split.h" |
23 #include "base/strings/stringprintf.h" | 25 #include "base/strings/stringprintf.h" |
24 #include "chrome/browser/themes/theme_properties.h" | 26 #include "chrome/browser/themes/theme_properties.h" |
25 #include "chrome/browser/ui/libgtk2ui/app_indicator_icon.h" | 27 #include "chrome/browser/ui/libgtk2ui/app_indicator_icon.h" |
26 #include "chrome/browser/ui/libgtk2ui/gtk2_event_loop.h" | 28 #include "chrome/browser/ui/libgtk2ui/gtk2_event_loop.h" |
27 #include "chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.h" | 29 #include "chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.h" |
28 #include "chrome/browser/ui/libgtk2ui/gtk2_status_icon.h" | 30 #include "chrome/browser/ui/libgtk2ui/gtk2_status_icon.h" |
29 #include "chrome/browser/ui/libgtk2ui/gtk2_util.h" | 31 #include "chrome/browser/ui/libgtk2ui/gtk2_util.h" |
30 #include "chrome/browser/ui/libgtk2ui/native_theme_gtk2.h" | 32 #include "chrome/browser/ui/libgtk2ui/native_theme_gtk2.h" |
31 #include "chrome/browser/ui/libgtk2ui/print_dialog_gtk2.h" | 33 #include "chrome/browser/ui/libgtk2ui/print_dialog_gtk2.h" |
32 #include "chrome/browser/ui/libgtk2ui/printing_gtk2_util.h" | 34 #include "chrome/browser/ui/libgtk2ui/printing_gtk2_util.h" |
33 #include "chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h" | 35 #include "chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h" |
34 #include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h" | 36 #include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h" |
35 #include "chrome/browser/ui/libgtk2ui/unity_service.h" | 37 #include "chrome/browser/ui/libgtk2ui/unity_service.h" |
36 #include "chrome/browser/ui/libgtk2ui/x11_input_method_context_impl_gtk2.h" | 38 #include "chrome/browser/ui/libgtk2ui/x11_input_method_context_impl_gtk2.h" |
39 #include "chrome/common/chrome_switches.h" | |
37 #include "chrome/grit/theme_resources.h" | 40 #include "chrome/grit/theme_resources.h" |
38 #include "components/grit/components_scaled_resources.h" | 41 #include "components/grit/components_scaled_resources.h" |
39 #include "third_party/skia/include/core/SkBitmap.h" | 42 #include "third_party/skia/include/core/SkBitmap.h" |
40 #include "third_party/skia/include/core/SkCanvas.h" | 43 #include "third_party/skia/include/core/SkCanvas.h" |
41 #include "third_party/skia/include/core/SkColor.h" | 44 #include "third_party/skia/include/core/SkColor.h" |
42 #include "third_party/skia/include/core/SkShader.h" | 45 #include "third_party/skia/include/core/SkShader.h" |
43 #include "ui/base/resource/resource_bundle.h" | 46 #include "ui/base/resource/resource_bundle.h" |
44 #include "ui/display/display.h" | 47 #include "ui/display/display.h" |
45 #include "ui/gfx/canvas.h" | 48 #include "ui/gfx/canvas.h" |
46 #include "ui/gfx/geometry/rect.h" | 49 #include "ui/gfx/geometry/rect.h" |
(...skipping 30 matching lines...) Expand all Loading... | |
77 // linux/debian_wheezy_i386-sysroot/usr/include/linux/stddef.h redefines NULL | 80 // linux/debian_wheezy_i386-sysroot/usr/include/linux/stddef.h redefines NULL |
78 // to 0, which breaks -Wsentinel. Get back the normal definition of NULL. | 81 // to 0, which breaks -Wsentinel. Get back the normal definition of NULL. |
79 // TODO(thakis): Remove this once we update sysroots. | 82 // TODO(thakis): Remove this once we update sysroots. |
80 #define __need_NULL | 83 #define __need_NULL |
81 #include <stddef.h> | 84 #include <stddef.h> |
82 | 85 |
83 namespace libgtk2ui { | 86 namespace libgtk2ui { |
84 | 87 |
85 namespace { | 88 namespace { |
86 | 89 |
90 const double kDefaultDPI = 96; | |
91 | |
87 class GtkButtonImageSource : public gfx::ImageSkiaSource { | 92 class GtkButtonImageSource : public gfx::ImageSkiaSource { |
88 public: | 93 public: |
89 GtkButtonImageSource(const char* idr_string, gfx::Size size) | 94 GtkButtonImageSource(const char* idr_string, gfx::Size size) |
90 : width_(size.width()), height_(size.height()) { | 95 : width_(size.width()), height_(size.height()) { |
91 is_blue_ = !!strstr(idr_string, "IDR_BLUE"); | 96 is_blue_ = !!strstr(idr_string, "IDR_BLUE"); |
92 focus_ = !!strstr(idr_string, "_FOCUSED_"); | 97 focus_ = !!strstr(idr_string, "_FOCUSED_"); |
93 | 98 |
94 if (strstr(idr_string, "_DISABLED")) { | 99 if (strstr(idr_string, "_DISABLED")) { |
95 state_ = ui::NativeTheme::kDisabled; | 100 state_ = ui::NativeTheme::kDisabled; |
96 } else if (strstr(idr_string, "_HOVER")) { | 101 } else if (strstr(idr_string, "_HOVER")) { |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
345 LOG(WARNING) << "Unexpected gtk-xft-rgba \"" << rgba << "\""; | 350 LOG(WARNING) << "Unexpected gtk-xft-rgba \"" << rgba << "\""; |
346 params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE; | 351 params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE; |
347 } | 352 } |
348 | 353 |
349 g_free(hint_style); | 354 g_free(hint_style); |
350 g_free(rgba); | 355 g_free(rgba); |
351 | 356 |
352 return params; | 357 return params; |
353 } | 358 } |
354 | 359 |
355 double GetDPI() { | 360 double GetDPI() { |
Evan Stade
2016/10/25 17:27:02
nit: GetDpi
| |
356 // Linux chrome currently does not support dynamic DPI changes. | 361 if (display::Display::HasForceDeviceScaleFactor()) |
357 // Keep using the first value detected. | 362 return display::Display::GetForcedDeviceScaleFactor() * kDefaultDPI; |
358 static double dpi = -1.f; | |
359 if (dpi < 0) { | |
360 const double kDefaultDPI = 96; | |
361 | 363 |
362 if (display::Display::HasForceDeviceScaleFactor()) { | 364 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
363 dpi = display::Display::GetForcedDeviceScaleFactor() * kDefaultDPI; | 365 switches::kEnableXDpiForDsf)) { |
364 return dpi; | 366 XDisplay* xdisplay = gfx::GetXDisplay(); |
365 } | 367 int xscreen = DefaultScreen(xdisplay); |
368 return (DisplayHeight(xdisplay, xscreen) * 25.4) / | |
369 DisplayHeightMM(xdisplay, xscreen); | |
370 } | |
366 | 371 |
367 GtkSettings* gtk_settings = gtk_settings_get_default(); | 372 GtkSettings* gtk_settings = gtk_settings_get_default(); |
368 CHECK(gtk_settings); | 373 CHECK(gtk_settings); |
369 gint gtk_dpi = -1; | 374 gint gtk_dpi = -1; |
370 g_object_get(gtk_settings, "gtk-xft-dpi", >k_dpi, NULL); | 375 g_object_get(gtk_settings, "gtk-xft-dpi", >k_dpi, NULL); |
371 | 376 |
372 // GTK multiplies the DPI by 1024 before storing it. | 377 // GTK multiplies the DPI by 1024 before storing it. |
373 dpi = (gtk_dpi > 0) ? gtk_dpi / 1024.0 : kDefaultDPI; | 378 return (gtk_dpi > 0) ? gtk_dpi / 1024.0 : kDefaultDPI; |
374 | |
375 // DSF is always >=1.0 on win/cros and lower DSF has never been considered | |
376 // nor tested. | |
377 dpi = std::max(kDefaultDPI, dpi); | |
378 } | |
379 return dpi; | |
380 } | 379 } |
381 | 380 |
382 // Queries GTK for its font DPI setting and returns the number of pixels in a | 381 float GetRawDeviceScaleFactor() { |
383 // point. | 382 if (display::Display::HasForceDeviceScaleFactor()) |
384 double GetPixelsInPoint(float device_scale_factor) { | 383 return display::Display::GetForcedDeviceScaleFactor(); |
385 double dpi = GetDPI(); | 384 return GetDPI() / kDefaultDPI; |
385 } | |
386 | |
387 // Returns the font size for the *raw* device scale factor in points. | |
388 // The |device_scale_factor| is used to cancel the scale to be applied by UI | |
389 // and to compensate the scale when the device_scale_factor is floored. | |
390 double GetFontSizePixelsInPoint(float device_scale_factor) { | |
391 // There are 72 points in an inch. | |
392 double point = GetDPI() / 72.0; | |
386 | 393 |
387 // Take device_scale_factor into account — if Chrome already scales the | 394 // Take device_scale_factor into account — if Chrome already scales the |
388 // entire UI up by 2x, we should not also scale up. | 395 // entire UI up by 2x, we should not also scale up. |
389 dpi /= device_scale_factor; | 396 point /= device_scale_factor; |
390 | 397 |
391 // There are 72 points in an inch. | 398 // Allow the scale lower than 1.0 only for fonts. Don't always use |
392 return dpi / 72.0; | 399 // the raw value however, beacuse the 1.0~1.3 is rounded to 1.0. |
400 float raw_scale = GetRawDeviceScaleFactor(); | |
401 if (raw_scale < 1.0f) | |
402 return point * raw_scale / device_scale_factor; | |
403 return point; | |
393 } | 404 } |
394 | 405 |
395 views::LinuxUI::NonClientMiddleClickAction GetDefaultMiddleClickAction() { | 406 views::LinuxUI::NonClientMiddleClickAction GetDefaultMiddleClickAction() { |
396 std::unique_ptr<base::Environment> env(base::Environment::Create()); | 407 std::unique_ptr<base::Environment> env(base::Environment::Create()); |
397 switch (base::nix::GetDesktopEnvironment(env.get())) { | 408 switch (base::nix::GetDesktopEnvironment(env.get())) { |
398 case base::nix::DESKTOP_ENVIRONMENT_KDE4: | 409 case base::nix::DESKTOP_ENVIRONMENT_KDE4: |
399 case base::nix::DESKTOP_ENVIRONMENT_KDE5: | 410 case base::nix::DESKTOP_ENVIRONMENT_KDE5: |
400 // Starting with KDE 4.4, windows' titlebars can be dragged with the | 411 // Starting with KDE 4.4, windows' titlebars can be dragged with the |
401 // middle mouse button to create tab groups. We don't support that in | 412 // middle mouse button to create tab groups. We don't support that in |
402 // Chrome, but at least avoid lowering windows in response to middle | 413 // Chrome, but at least avoid lowering windows in response to middle |
403 // clicks to avoid surprising users who expect the KDE behavior. | 414 // clicks to avoid surprising users who expect the KDE behavior. |
404 return views::LinuxUI::MIDDLE_CLICK_ACTION_NONE; | 415 return views::LinuxUI::MIDDLE_CLICK_ACTION_NONE; |
405 default: | 416 default: |
406 return views::LinuxUI::MIDDLE_CLICK_ACTION_LOWER; | 417 return views::LinuxUI::MIDDLE_CLICK_ACTION_LOWER; |
407 } | 418 } |
408 } | 419 } |
409 | 420 |
410 } // namespace | 421 } // namespace |
411 | 422 |
412 Gtk2UI::Gtk2UI() | 423 Gtk2UI::Gtk2UI() |
413 : default_font_size_pixels_(0), | 424 : default_font_size_pixels_(0), |
414 default_font_style_(gfx::Font::NORMAL), | 425 default_font_style_(gfx::Font::NORMAL), |
415 default_font_weight_(gfx::Font::Weight::NORMAL), | 426 default_font_weight_(gfx::Font::Weight::NORMAL), |
416 middle_click_action_(GetDefaultMiddleClickAction()), | 427 middle_click_action_(GetDefaultMiddleClickAction()) { |
417 device_scale_factor_(1.0) { | |
418 GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); | 428 GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); |
419 } | 429 } |
420 | 430 |
421 Gtk2UI::~Gtk2UI() {} | 431 Gtk2UI::~Gtk2UI() {} |
422 | 432 |
423 void OnThemeChanged(GObject* obj, GParamSpec* param, Gtk2UI* gtkui) { | 433 void OnThemeChanged(GObject* obj, GParamSpec* param, Gtk2UI* gtkui) { |
424 gtkui->ResetStyle(); | 434 gtkui->ResetStyle(); |
425 } | 435 } |
426 | 436 |
427 void Gtk2UI::Initialize() { | 437 void Gtk2UI::Initialize() { |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
806 colors_[ThemeProperties::COLOR_TOOLBAR] = toolbar_color; | 816 colors_[ThemeProperties::COLOR_TOOLBAR] = toolbar_color; |
807 | 817 |
808 colors_[ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON] = | 818 colors_[ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON] = |
809 color_utils::DeriveDefaultIconColor(label_color); | 819 color_utils::DeriveDefaultIconColor(label_color); |
810 | 820 |
811 colors_[ThemeProperties::COLOR_TAB_TEXT] = label_color; | 821 colors_[ThemeProperties::COLOR_TAB_TEXT] = label_color; |
812 colors_[ThemeProperties::COLOR_BOOKMARK_TEXT] = label_color; | 822 colors_[ThemeProperties::COLOR_BOOKMARK_TEXT] = label_color; |
813 colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] = | 823 colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] = |
814 color_utils::BlendTowardOppositeLuma(label_color, 50); | 824 color_utils::BlendTowardOppositeLuma(label_color, 50); |
815 | 825 |
816 UpdateDefaultFont(); | 826 UpdateDeviceScaleFactor(); |
817 | 827 |
818 // Build the various icon tints. | 828 // Build the various icon tints. |
819 GetNormalButtonTintHSL(&button_tint_); | 829 GetNormalButtonTintHSL(&button_tint_); |
820 GetNormalEntryForegroundHSL(&entry_tint_); | 830 GetNormalEntryForegroundHSL(&entry_tint_); |
821 GetSelectedEntryForegroundHSL(&selected_entry_tint_); | 831 GetSelectedEntryForegroundHSL(&selected_entry_tint_); |
822 | 832 |
823 // We pick the text and background colors for the NTP out of the colors for a | 833 // We pick the text and background colors for the NTP out of the colors for a |
824 // GtkEntry. We do this because GtkEntries background color is never the same | 834 // GtkEntry. We do this because GtkEntries background color is never the same |
825 // as |toolbar_color|, is usually a white, and when it isn't a white, | 835 // as |toolbar_color|, is usually a white, and when it isn't a white, |
826 // provides sufficient contrast to |toolbar_color|. Try this out with | 836 // provides sufficient contrast to |toolbar_color|. Try this out with |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1039 // If the size is absolute, it's specified in Pango units. There are | 1049 // If the size is absolute, it's specified in Pango units. There are |
1040 // PANGO_SCALE Pango units in a device unit (pixel). | 1050 // PANGO_SCALE Pango units in a device unit (pixel). |
1041 const int size_pixels = pango_font_description_get_size(desc) / PANGO_SCALE; | 1051 const int size_pixels = pango_font_description_get_size(desc) / PANGO_SCALE; |
1042 default_font_size_pixels_ = size_pixels; | 1052 default_font_size_pixels_ = size_pixels; |
1043 query.pixel_size = size_pixels; | 1053 query.pixel_size = size_pixels; |
1044 } else { | 1054 } else { |
1045 // Non-absolute sizes are in points (again scaled by PANGO_SIZE). | 1055 // Non-absolute sizes are in points (again scaled by PANGO_SIZE). |
1046 // Round the value when converting to pixels to match GTK's logic. | 1056 // Round the value when converting to pixels to match GTK's logic. |
1047 const double size_points = pango_font_description_get_size(desc) / | 1057 const double size_points = pango_font_description_get_size(desc) / |
1048 static_cast<double>(PANGO_SCALE); | 1058 static_cast<double>(PANGO_SCALE); |
1049 default_font_size_pixels_ = static_cast<int>( | 1059 default_font_size_pixels_ = std::round( |
1050 GetPixelsInPoint(device_scale_factor_) * size_points + 0.5); | 1060 GetFontSizePixelsInPoint(GetDeviceScaleFactor()) * size_points); |
1051 query.point_size = static_cast<int>(size_points); | 1061 query.point_size = static_cast<int>(size_points); |
1052 } | 1062 } |
1053 | 1063 |
1054 query.style = gfx::Font::NORMAL; | 1064 query.style = gfx::Font::NORMAL; |
1055 query.weight = | 1065 query.weight = |
1056 static_cast<gfx::Font::Weight>(pango_font_description_get_weight(desc)); | 1066 static_cast<gfx::Font::Weight>(pango_font_description_get_weight(desc)); |
1057 // TODO(davemoore): What about PANGO_STYLE_OBLIQUE? | 1067 // TODO(davemoore): What about PANGO_STYLE_OBLIQUE? |
1058 if (pango_font_description_get_style(desc) == PANGO_STYLE_ITALIC) | 1068 if (pango_font_description_get_style(desc) == PANGO_STYLE_ITALIC) |
1059 query.style |= gfx::Font::ITALIC; | 1069 query.style |= gfx::Font::ITALIC; |
1060 | 1070 |
1061 default_font_render_params_ = | 1071 default_font_render_params_ = |
1062 gfx::GetFontRenderParams(query, &default_font_family_); | 1072 gfx::GetFontRenderParams(query, &default_font_family_); |
1063 default_font_style_ = query.style; | 1073 default_font_style_ = query.style; |
1064 } | 1074 } |
1065 | 1075 |
1066 void Gtk2UI::ResetStyle() { | 1076 void Gtk2UI::ResetStyle() { |
1067 LoadGtkValues(); | 1077 LoadGtkValues(); |
1068 NativeThemeGtk2::instance()->NotifyObservers(); | 1078 NativeThemeGtk2::instance()->NotifyObservers(); |
1069 } | 1079 } |
1070 | 1080 |
1071 void Gtk2UI::UpdateDeviceScaleFactor(float device_scale_factor) { | 1081 void Gtk2UI::UpdateDeviceScaleFactor() { |
1072 device_scale_factor_ = device_scale_factor; | 1082 // Note: Linux chrome currently does not support dynamic DPI |
1083 // changes. This is to allow flags to override the DPI settings | |
1084 // during startup. | |
1085 float scale = GetRawDeviceScaleFactor(); | |
1086 | |
1087 // Blacklist scaling factors <130% (crbug.com/484400) and round | |
1088 // to 1 decimal to prevent rendering problems (crbug.com/485183). | |
1089 device_scale_factor_ = scale < 1.3f ? 1.0f : roundf(scale * 10) / 10; | |
1073 UpdateDefaultFont(); | 1090 UpdateDefaultFont(); |
1074 } | 1091 } |
1075 | 1092 |
1076 float Gtk2UI::GetDeviceScaleFactor() const { | 1093 float Gtk2UI::GetDeviceScaleFactor() const { |
1077 if (display::Display::HasForceDeviceScaleFactor()) | 1094 return device_scale_factor_; |
1078 return display::Display::GetForcedDeviceScaleFactor(); | |
1079 const int kCSSDefaultDPI = 96; | |
1080 const float scale = GetDPI() / kCSSDefaultDPI; | |
1081 | |
1082 // Blacklist scaling factors <130% (crbug.com/484400) and round | |
1083 // to 1 decimal to prevent rendering problems (crbug.com/485183). | |
1084 return scale < 1.3f ? 1.0f : roundf(scale * 10) / 10; | |
1085 } | 1095 } |
1086 | 1096 |
1087 } // namespace libgtk2ui | 1097 } // namespace libgtk2ui |
1088 | 1098 |
1089 views::LinuxUI* BuildGtk2UI() { | 1099 views::LinuxUI* BuildGtk2UI() { |
1090 return new libgtk2ui::Gtk2UI; | 1100 return new libgtk2ui::Gtk2UI; |
1091 } | 1101 } |
OLD | NEW |