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 |