Chromium Code Reviews| 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/libgtkui/gtk_ui.h" | 5 #include "chrome/browser/ui/libgtkui/gtk_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" |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 77 // linux/debian_wheezy_i386-sysroot/usr/include/linux/stddef.h redefines NULL | 79 // 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. | 80 // to 0, which breaks -Wsentinel. Get back the normal definition of NULL. |
| 79 // TODO(thakis): Remove this once we update sysroots. | 81 // TODO(thakis): Remove this once we update sysroots. |
| 80 #define __need_NULL | 82 #define __need_NULL |
| 81 #include <stddef.h> | 83 #include <stddef.h> |
| 82 | 84 |
| 83 namespace libgtkui { | 85 namespace libgtkui { |
| 84 | 86 |
| 85 namespace { | 87 namespace { |
| 86 | 88 |
| 89 const double kDefaultDPI = 96; | |
| 90 | |
| 87 class GtkButtonImageSource : public gfx::ImageSkiaSource { | 91 class GtkButtonImageSource : public gfx::ImageSkiaSource { |
| 88 public: | 92 public: |
| 89 GtkButtonImageSource(const char* idr_string, gfx::Size size) | 93 GtkButtonImageSource(const char* idr_string, gfx::Size size) |
| 90 : width_(size.width()), height_(size.height()) { | 94 : width_(size.width()), height_(size.height()) { |
| 91 is_blue_ = !!strstr(idr_string, "IDR_BLUE"); | 95 is_blue_ = !!strstr(idr_string, "IDR_BLUE"); |
| 92 focus_ = !!strstr(idr_string, "_FOCUSED_"); | 96 focus_ = !!strstr(idr_string, "_FOCUSED_"); |
| 93 | 97 |
| 94 if (strstr(idr_string, "_DISABLED")) { | 98 if (strstr(idr_string, "_DISABLED")) { |
| 95 state_ = ui::NativeTheme::kDisabled; | 99 state_ = ui::NativeTheme::kDisabled; |
| 96 } else if (strstr(idr_string, "_HOVER")) { | 100 } else if (strstr(idr_string, "_HOVER")) { |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 343 LOG(WARNING) << "Unexpected gtk-xft-rgba \"" << rgba << "\""; | 347 LOG(WARNING) << "Unexpected gtk-xft-rgba \"" << rgba << "\""; |
| 344 params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE; | 348 params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE; |
| 345 } | 349 } |
| 346 | 350 |
| 347 g_free(hint_style); | 351 g_free(hint_style); |
| 348 g_free(rgba); | 352 g_free(rgba); |
| 349 | 353 |
| 350 return params; | 354 return params; |
| 351 } | 355 } |
| 352 | 356 |
| 353 double GetDPI() { | 357 double GetDpi() { |
| 354 // Linux chrome currently does not support dynamic DPI changes. | 358 if (display::Display::HasForceDeviceScaleFactor()) |
| 355 // Keep using the first value detected. | 359 return display::Display::GetForcedDeviceScaleFactor() * kDefaultDPI; |
| 356 static double dpi = -1.f; | |
| 357 if (dpi < 0) { | |
| 358 const double kDefaultDPI = 96; | |
| 359 | 360 |
| 360 if (display::Display::HasForceDeviceScaleFactor()) { | 361 GtkSettings* gtk_settings = gtk_settings_get_default(); |
| 361 dpi = display::Display::GetForcedDeviceScaleFactor() * kDefaultDPI; | 362 CHECK(gtk_settings); |
| 362 return dpi; | 363 gint gtk_dpi = -1; |
| 363 } | 364 g_object_get(gtk_settings, "gtk-xft-dpi", >k_dpi, NULL); |
| 364 | 365 |
| 365 GtkSettings* gtk_settings = gtk_settings_get_default(); | 366 // GTK multiplies the DPI by 1024 before storing it. |
| 366 CHECK(gtk_settings); | 367 return (gtk_dpi > 0) ? gtk_dpi / 1024.0 : kDefaultDPI; |
| 367 gint gtk_dpi = -1; | |
| 368 g_object_get(gtk_settings, "gtk-xft-dpi", >k_dpi, NULL); | |
| 369 | |
| 370 // GTK multiplies the DPI by 1024 before storing it. | |
| 371 dpi = (gtk_dpi > 0) ? gtk_dpi / 1024.0 : kDefaultDPI; | |
| 372 | |
| 373 // DSF is always >=1.0 on win/cros and lower DSF has never been considered | |
| 374 // nor tested. | |
| 375 dpi = std::max(kDefaultDPI, dpi); | |
| 376 } | |
| 377 return dpi; | |
| 378 } | 368 } |
| 379 | 369 |
| 380 // Queries GTK for its font DPI setting and returns the number of pixels in a | 370 float GetRawDeviceScaleFactor() { |
| 381 // point. | 371 if (display::Display::HasForceDeviceScaleFactor()) |
| 382 double GetPixelsInPoint(float device_scale_factor) { | 372 return display::Display::GetForcedDeviceScaleFactor(); |
| 383 double dpi = GetDPI(); | 373 return GetDpi() / kDefaultDPI; |
| 374 } | |
| 375 | |
| 376 // Returns the font size for the *raw* device scale factor in points. | |
| 377 // The |device_scale_factor| is used to cancel the scale to be applied by UI | |
| 378 // and to compensate the scale when the device_scale_factor is floored. | |
| 379 double GetFontSizePixelsInPoint(float device_scale_factor) { | |
|
Evan Stade
2016/11/03 16:38:03
perhaps this param could be called ui_scale_factor
oshima
2016/11/05 15:15:05
changed to ui_device_scale_factor.
| |
| 380 // There are 72 points in an inch. | |
| 381 double point = GetDpi() / 72.0; | |
| 384 | 382 |
| 385 // Take device_scale_factor into account — if Chrome already scales the | 383 // Take device_scale_factor into account — if Chrome already scales the |
| 386 // entire UI up by 2x, we should not also scale up. | 384 // entire UI up by 2x, we should not also scale up. |
| 387 dpi /= device_scale_factor; | 385 point /= device_scale_factor; |
| 388 | 386 |
| 389 // There are 72 points in an inch. | 387 // Allow the scale lower than 1.0 only for fonts. Don't always use |
| 390 return dpi / 72.0; | 388 // the raw value however, beacuse the 1.0~1.3 is rounded to 1.0. |
|
Evan Stade
2016/11/03 16:38:03
why not allow users to bump font size slightly? Th
oshima
2016/11/05 15:15:05
I want to keep the current behavior for dsf>1 case
| |
| 389 float raw_scale = GetRawDeviceScaleFactor(); | |
| 390 if (raw_scale < 1.0f) | |
| 391 return point * raw_scale / device_scale_factor; | |
| 392 return point; | |
| 391 } | 393 } |
| 392 | 394 |
| 393 views::LinuxUI::NonClientMiddleClickAction GetDefaultMiddleClickAction() { | 395 views::LinuxUI::NonClientMiddleClickAction GetDefaultMiddleClickAction() { |
| 394 std::unique_ptr<base::Environment> env(base::Environment::Create()); | 396 std::unique_ptr<base::Environment> env(base::Environment::Create()); |
| 395 switch (base::nix::GetDesktopEnvironment(env.get())) { | 397 switch (base::nix::GetDesktopEnvironment(env.get())) { |
| 396 case base::nix::DESKTOP_ENVIRONMENT_KDE4: | 398 case base::nix::DESKTOP_ENVIRONMENT_KDE4: |
| 397 case base::nix::DESKTOP_ENVIRONMENT_KDE5: | 399 case base::nix::DESKTOP_ENVIRONMENT_KDE5: |
| 398 // Starting with KDE 4.4, windows' titlebars can be dragged with the | 400 // Starting with KDE 4.4, windows' titlebars can be dragged with the |
| 399 // middle mouse button to create tab groups. We don't support that in | 401 // middle mouse button to create tab groups. We don't support that in |
| 400 // Chrome, but at least avoid lowering windows in response to middle | 402 // Chrome, but at least avoid lowering windows in response to middle |
| 401 // clicks to avoid surprising users who expect the KDE behavior. | 403 // clicks to avoid surprising users who expect the KDE behavior. |
| 402 return views::LinuxUI::MIDDLE_CLICK_ACTION_NONE; | 404 return views::LinuxUI::MIDDLE_CLICK_ACTION_NONE; |
| 403 default: | 405 default: |
| 404 return views::LinuxUI::MIDDLE_CLICK_ACTION_LOWER; | 406 return views::LinuxUI::MIDDLE_CLICK_ACTION_LOWER; |
| 405 } | 407 } |
| 406 } | 408 } |
| 407 | 409 |
| 408 } // namespace | 410 } // namespace |
| 409 | 411 |
| 410 Gtk2UI::Gtk2UI() | 412 Gtk2UI::Gtk2UI() |
| 411 : default_font_size_pixels_(0), | 413 : default_font_size_pixels_(0), |
| 412 default_font_style_(gfx::Font::NORMAL), | 414 default_font_style_(gfx::Font::NORMAL), |
| 413 default_font_weight_(gfx::Font::Weight::NORMAL), | 415 default_font_weight_(gfx::Font::Weight::NORMAL), |
| 414 middle_click_action_(GetDefaultMiddleClickAction()), | 416 middle_click_action_(GetDefaultMiddleClickAction()) { |
| 415 device_scale_factor_(1.0) { | |
| 416 GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); | 417 GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); |
| 417 } | 418 } |
| 418 | 419 |
| 419 Gtk2UI::~Gtk2UI() {} | 420 Gtk2UI::~Gtk2UI() {} |
| 420 | 421 |
| 421 void OnThemeChanged(GObject* obj, GParamSpec* param, Gtk2UI* gtkui) { | 422 void OnThemeChanged(GObject* obj, GParamSpec* param, Gtk2UI* gtkui) { |
| 422 gtkui->ResetStyle(); | 423 gtkui->ResetStyle(); |
| 423 } | 424 } |
| 424 | 425 |
| 425 void Gtk2UI::Initialize() { | 426 void Gtk2UI::Initialize() { |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 803 colors_[ThemeProperties::COLOR_TOOLBAR] = toolbar_color; | 804 colors_[ThemeProperties::COLOR_TOOLBAR] = toolbar_color; |
| 804 | 805 |
| 805 colors_[ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON] = | 806 colors_[ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON] = |
| 806 color_utils::DeriveDefaultIconColor(label_color); | 807 color_utils::DeriveDefaultIconColor(label_color); |
| 807 | 808 |
| 808 colors_[ThemeProperties::COLOR_TAB_TEXT] = label_color; | 809 colors_[ThemeProperties::COLOR_TAB_TEXT] = label_color; |
| 809 colors_[ThemeProperties::COLOR_BOOKMARK_TEXT] = label_color; | 810 colors_[ThemeProperties::COLOR_BOOKMARK_TEXT] = label_color; |
| 810 colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] = | 811 colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] = |
| 811 color_utils::BlendTowardOppositeLuma(label_color, 50); | 812 color_utils::BlendTowardOppositeLuma(label_color, 50); |
| 812 | 813 |
| 813 UpdateDefaultFont(); | 814 UpdateDeviceScaleFactor(); |
| 814 | 815 |
| 815 // Build the various icon tints. | 816 // Build the various icon tints. |
| 816 GetNormalButtonTintHSL(&button_tint_); | 817 GetNormalButtonTintHSL(&button_tint_); |
| 817 GetNormalEntryForegroundHSL(&entry_tint_); | 818 GetNormalEntryForegroundHSL(&entry_tint_); |
| 818 GetSelectedEntryForegroundHSL(&selected_entry_tint_); | 819 GetSelectedEntryForegroundHSL(&selected_entry_tint_); |
| 819 | 820 |
| 820 // We pick the text and background colors for the NTP out of the colors for a | 821 // We pick the text and background colors for the NTP out of the colors for a |
| 821 // GtkEntry. We do this because GtkEntries background color is never the same | 822 // GtkEntry. We do this because GtkEntries background color is never the same |
| 822 // as |toolbar_color|, is usually a white, and when it isn't a white, | 823 // as |toolbar_color|, is usually a white, and when it isn't a white, |
| 823 // provides sufficient contrast to |toolbar_color|. Try this out with | 824 // provides sufficient contrast to |toolbar_color|. Try this out with |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1023 // PANGO_SCALE Pango units in a device unit (pixel). | 1024 // PANGO_SCALE Pango units in a device unit (pixel). |
| 1024 const int size_pixels = pango_font_description_get_size(desc) / PANGO_SCALE; | 1025 const int size_pixels = pango_font_description_get_size(desc) / PANGO_SCALE; |
| 1025 default_font_size_pixels_ = size_pixels; | 1026 default_font_size_pixels_ = size_pixels; |
| 1026 query.pixel_size = size_pixels; | 1027 query.pixel_size = size_pixels; |
| 1027 } else { | 1028 } else { |
| 1028 // Non-absolute sizes are in points (again scaled by PANGO_SIZE). | 1029 // Non-absolute sizes are in points (again scaled by PANGO_SIZE). |
| 1029 // Round the value when converting to pixels to match GTK's logic. | 1030 // Round the value when converting to pixels to match GTK's logic. |
| 1030 const double size_points = pango_font_description_get_size(desc) / | 1031 const double size_points = pango_font_description_get_size(desc) / |
| 1031 static_cast<double>(PANGO_SCALE); | 1032 static_cast<double>(PANGO_SCALE); |
| 1032 default_font_size_pixels_ = static_cast<int>( | 1033 default_font_size_pixels_ = static_cast<int>( |
| 1033 GetPixelsInPoint(device_scale_factor_) * size_points + 0.5); | 1034 GetFontSizePixelsInPoint(GetDeviceScaleFactor()) * size_points); |
| 1034 query.point_size = static_cast<int>(size_points); | 1035 query.point_size = static_cast<int>(size_points); |
| 1035 } | 1036 } |
| 1036 | 1037 |
| 1037 query.style = gfx::Font::NORMAL; | 1038 query.style = gfx::Font::NORMAL; |
| 1038 query.weight = | 1039 query.weight = |
| 1039 static_cast<gfx::Font::Weight>(pango_font_description_get_weight(desc)); | 1040 static_cast<gfx::Font::Weight>(pango_font_description_get_weight(desc)); |
| 1040 // TODO(davemoore): What about PANGO_STYLE_OBLIQUE? | 1041 // TODO(davemoore): What about PANGO_STYLE_OBLIQUE? |
| 1041 if (pango_font_description_get_style(desc) == PANGO_STYLE_ITALIC) | 1042 if (pango_font_description_get_style(desc) == PANGO_STYLE_ITALIC) |
| 1042 query.style |= gfx::Font::ITALIC; | 1043 query.style |= gfx::Font::ITALIC; |
| 1043 | 1044 |
| 1044 default_font_render_params_ = | 1045 default_font_render_params_ = |
| 1045 gfx::GetFontRenderParams(query, &default_font_family_); | 1046 gfx::GetFontRenderParams(query, &default_font_family_); |
| 1046 default_font_style_ = query.style; | 1047 default_font_style_ = query.style; |
| 1047 } | 1048 } |
| 1048 | 1049 |
| 1049 void Gtk2UI::ResetStyle() { | 1050 void Gtk2UI::ResetStyle() { |
| 1050 LoadGtkValues(); | 1051 LoadGtkValues(); |
| 1051 NativeThemeGtk2::instance()->NotifyObservers(); | 1052 NativeThemeGtk2::instance()->NotifyObservers(); |
| 1052 } | 1053 } |
| 1053 | 1054 |
| 1054 void Gtk2UI::UpdateDeviceScaleFactor(float device_scale_factor) { | 1055 void Gtk2UI::UpdateDeviceScaleFactor() { |
| 1055 device_scale_factor_ = device_scale_factor; | 1056 // Note: Linux chrome currently does not support dynamic DPI |
| 1057 // changes. This is to allow flags to override the DPI settings | |
| 1058 // during startup. | |
| 1059 float scale = GetRawDeviceScaleFactor(); | |
| 1060 | |
| 1061 // Blacklist scaling factors <130% (crbug.com/484400) and round | |
| 1062 // to 1 decimal to prevent rendering problems (crbug.com/485183). | |
| 1063 device_scale_factor_ = scale < 1.3f ? 1.0f : roundf(scale * 10) / 10; | |
| 1056 UpdateDefaultFont(); | 1064 UpdateDefaultFont(); |
| 1057 } | 1065 } |
| 1058 | 1066 |
| 1059 float Gtk2UI::GetDeviceScaleFactor() const { | 1067 float Gtk2UI::GetDeviceScaleFactor() const { |
| 1060 if (display::Display::HasForceDeviceScaleFactor()) | 1068 return device_scale_factor_; |
| 1061 return display::Display::GetForcedDeviceScaleFactor(); | |
| 1062 const int kCSSDefaultDPI = 96; | |
| 1063 const float scale = GetDPI() / kCSSDefaultDPI; | |
| 1064 | |
| 1065 // Blacklist scaling factors <130% (crbug.com/484400) and round | |
| 1066 // to 1 decimal to prevent rendering problems (crbug.com/485183). | |
| 1067 return scale < 1.3f ? 1.0f : roundf(scale * 10) / 10; | |
| 1068 } | 1069 } |
| 1069 | 1070 |
| 1070 } // namespace libgtkui | 1071 } // namespace libgtkui |
| 1071 | 1072 |
| 1072 views::LinuxUI* BuildGtk2UI() { | 1073 views::LinuxUI* BuildGtk2UI() { |
| 1073 return new libgtkui::Gtk2UI; | 1074 return new libgtkui::Gtk2UI; |
| 1074 } | 1075 } |
| OLD | NEW |