Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(113)

Side by Side Diff: chrome/browser/ui/libgtkui/gtk_ui.cc

Issue 2963033002: Linux UI: Dynamically respond to changes in the scale factor (Closed)
Patch Set: LinuxUI may not exist in test scenarios Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/ui/libgtkui/gtk_ui.h ('k') | ui/views/linux_ui/device_scale_factor_observer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <X11/Xcursor/Xcursor.h> 7 #include <X11/Xcursor/Xcursor.h>
8 #include <dlfcn.h> 8 #include <dlfcn.h>
9 #include <math.h> 9 #include <math.h>
10 #include <pango/pango.h> 10 #include <pango/pango.h>
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 #include "ui/gfx/geometry/size.h" 51 #include "ui/gfx/geometry/size.h"
52 #include "ui/gfx/image/image.h" 52 #include "ui/gfx/image/image.h"
53 #include "ui/gfx/image/image_skia_source.h" 53 #include "ui/gfx/image/image_skia_source.h"
54 #include "ui/gfx/skbitmap_operations.h" 54 #include "ui/gfx/skbitmap_operations.h"
55 #include "ui/gfx/skia_util.h" 55 #include "ui/gfx/skia_util.h"
56 #include "ui/gfx/x/x11_types.h" 56 #include "ui/gfx/x/x11_types.h"
57 #include "ui/native_theme/native_theme.h" 57 #include "ui/native_theme/native_theme.h"
58 #include "ui/views/controls/button/blue_button.h" 58 #include "ui/views/controls/button/blue_button.h"
59 #include "ui/views/controls/button/label_button.h" 59 #include "ui/views/controls/button/label_button.h"
60 #include "ui/views/controls/button/label_button_border.h" 60 #include "ui/views/controls/button/label_button_border.h"
61 #include "ui/views/linux_ui/device_scale_factor_observer.h"
61 #include "ui/views/linux_ui/window_button_order_observer.h" 62 #include "ui/views/linux_ui/window_button_order_observer.h"
62 #include "ui/views/resources/grit/views_resources.h" 63 #include "ui/views/resources/grit/views_resources.h"
63 64
64 #if GTK_MAJOR_VERSION == 2 65 #if GTK_MAJOR_VERSION == 2
65 #include "chrome/browser/ui/libgtkui/native_theme_gtk2.h" // nogncheck 66 #include "chrome/browser/ui/libgtkui/native_theme_gtk2.h" // nogncheck
66 #elif GTK_MAJOR_VERSION == 3 67 #elif GTK_MAJOR_VERSION == 3
67 #include "chrome/browser/ui/libgtkui/native_theme_gtk3.h" // nogncheck 68 #include "chrome/browser/ui/libgtkui/native_theme_gtk3.h" // nogncheck
68 #endif 69 #endif
69 70
70 #if BUILDFLAG(ENABLE_BASIC_PRINTING) 71 #if BUILDFLAG(ENABLE_BASIC_PRINTING)
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 LOG(WARNING) << "Unexpected gtk-xft-rgba \"" << rgba << "\""; 307 LOG(WARNING) << "Unexpected gtk-xft-rgba \"" << rgba << "\"";
307 params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE; 308 params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE;
308 } 309 }
309 310
310 g_free(hint_style); 311 g_free(hint_style);
311 g_free(rgba); 312 g_free(rgba);
312 313
313 return params; 314 return params;
314 } 315 }
315 316
316 float GetRawDeviceScaleFactor() {
317 if (display::Display::HasForceDeviceScaleFactor())
318 return display::Display::GetForcedDeviceScaleFactor();
319
320 GdkScreen* screen = gdk_screen_get_default();
321 gint scale = gdk_screen_get_monitor_scale_factor(
322 screen, gdk_screen_get_primary_monitor(screen));
323 gdouble resolution = gdk_screen_get_resolution(screen);
324 const float scale_factor =
325 resolution <= 0 ? scale : resolution * scale / kDefaultDPI;
326 // Blacklist scaling factors <120% (crbug.com/484400) and round
327 // to 1 decimal to prevent rendering problems (crbug.com/485183).
328 return scale_factor < 1.2f ? 1.0f : roundf(scale_factor * 10) / 10;
329 }
330
331 views::LinuxUI::NonClientMiddleClickAction GetDefaultMiddleClickAction() { 317 views::LinuxUI::NonClientMiddleClickAction GetDefaultMiddleClickAction() {
332 std::unique_ptr<base::Environment> env(base::Environment::Create()); 318 std::unique_ptr<base::Environment> env(base::Environment::Create());
333 switch (base::nix::GetDesktopEnvironment(env.get())) { 319 switch (base::nix::GetDesktopEnvironment(env.get())) {
334 case base::nix::DESKTOP_ENVIRONMENT_KDE4: 320 case base::nix::DESKTOP_ENVIRONMENT_KDE4:
335 case base::nix::DESKTOP_ENVIRONMENT_KDE5: 321 case base::nix::DESKTOP_ENVIRONMENT_KDE5:
336 // Starting with KDE 4.4, windows' titlebars can be dragged with the 322 // Starting with KDE 4.4, windows' titlebars can be dragged with the
337 // middle mouse button to create tab groups. We don't support that in 323 // middle mouse button to create tab groups. We don't support that in
338 // Chrome, but at least avoid lowering windows in response to middle 324 // Chrome, but at least avoid lowering windows in response to middle
339 // clicks to avoid surprising users who expect the KDE behavior. 325 // clicks to avoid surprising users who expect the KDE behavior.
340 return views::LinuxUI::MIDDLE_CLICK_ACTION_NONE; 326 return views::LinuxUI::MIDDLE_CLICK_ACTION_NONE;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 dlsym(GetGdkSharedLibrary(), "gdk_set_allowed_backends")); 395 dlsym(GetGdkSharedLibrary(), "gdk_set_allowed_backends"));
410 if (GtkVersionCheck(3, 10)) 396 if (GtkVersionCheck(3, 10))
411 DCHECK(_gdk_set_allowed_backends); 397 DCHECK(_gdk_set_allowed_backends);
412 if (_gdk_set_allowed_backends) 398 if (_gdk_set_allowed_backends)
413 _gdk_set_allowed_backends("x11"); 399 _gdk_set_allowed_backends("x11");
414 #endif 400 #endif
415 GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); 401 GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess());
416 #if GTK_MAJOR_VERSION == 2 402 #if GTK_MAJOR_VERSION == 2
417 native_theme_ = NativeThemeGtk2::instance(); 403 native_theme_ = NativeThemeGtk2::instance();
418 fake_window_ = chrome_gtk_frame_new(); 404 fake_window_ = chrome_gtk_frame_new();
419 gtk_widget_realize(fake_window_); // Is this necessary?
420 #elif GTK_MAJOR_VERSION == 3 405 #elif GTK_MAJOR_VERSION == 3
421 native_theme_ = NativeThemeGtk3::instance(); 406 native_theme_ = NativeThemeGtk3::instance();
422 (void)fake_window_; // Silence the unused warning. 407 fake_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);
423 #else 408 #else
424 #error "Unsupported GTK version" 409 #error "Unsupported GTK version"
425 #endif 410 #endif
411 gtk_widget_realize(fake_window_);
426 } 412 }
427 413
428 GtkUi::~GtkUi() { 414 GtkUi::~GtkUi() {
429 #if GTK_MAJOR_VERSION == 2
430 gtk_widget_destroy(fake_window_); 415 gtk_widget_destroy(fake_window_);
431 #endif
432 } 416 }
433 417
434 void OnThemeChanged(GObject* obj, GParamSpec* param, GtkUi* gtkui) { 418 void OnThemeChanged(GObject* obj, GParamSpec* param, GtkUi* gtkui) {
435 gtkui->ResetStyle(); 419 gtkui->ResetStyle();
436 } 420 }
437 421
438 void GtkUi::Initialize() { 422 void GtkUi::Initialize() {
439 GtkSettings* settings = gtk_settings_get_default(); 423 GtkSettings* settings = gtk_settings_get_default();
440 g_signal_connect_after(settings, "notify::gtk-theme-name", 424 g_signal_connect_after(settings, "notify::gtk-theme-name",
441 G_CALLBACK(OnThemeChanged), this); 425 G_CALLBACK(OnThemeChanged), this);
442 g_signal_connect_after(settings, "notify::gtk-icon-theme-name", 426 g_signal_connect_after(settings, "notify::gtk-icon-theme-name",
443 G_CALLBACK(OnThemeChanged), this); 427 G_CALLBACK(OnThemeChanged), this);
444 428
429 GdkScreen* screen = gdk_screen_get_default();
430 // Listen for DPI changes.
431 g_signal_connect_after(screen, "notify::resolution",
432 G_CALLBACK(OnDeviceScaleFactorMaybeChangedThunk),
433 this);
434 // Listen for scale factor changes. We would prefer to listen on
435 // |screen|, but there is no scale-factor property, so use an
436 // unmapped window instead.
437 g_signal_connect(fake_window_, "notify::scale-factor",
438 G_CALLBACK(OnDeviceScaleFactorMaybeChangedThunk), this);
439
445 LoadGtkValues(); 440 LoadGtkValues();
446 441
447 #if BUILDFLAG(ENABLE_BASIC_PRINTING) 442 #if BUILDFLAG(ENABLE_BASIC_PRINTING)
448 printing::PrintingContextLinux::SetCreatePrintDialogFunction( 443 printing::PrintingContextLinux::SetCreatePrintDialogFunction(
449 &PrintDialogGtk2::CreatePrintDialog); 444 &PrintDialogGtk2::CreatePrintDialog);
450 printing::PrintingContextLinux::SetPdfPaperSizeFunction( 445 printing::PrintingContextLinux::SetPdfPaperSizeFunction(
451 &GetPdfPaperSizeDeviceUnitsGtk); 446 &GetPdfPaperSizeDeviceUnitsGtk);
452 #endif 447 #endif
453 448
454 #if defined(USE_GCONF) 449 #if defined(USE_GCONF)
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 691
697 return std::move(gtk_border); 692 return std::move(gtk_border);
698 } 693 }
699 694
700 void GtkUi::AddWindowButtonOrderObserver( 695 void GtkUi::AddWindowButtonOrderObserver(
701 views::WindowButtonOrderObserver* observer) { 696 views::WindowButtonOrderObserver* observer) {
702 if (!leading_buttons_.empty() || !trailing_buttons_.empty()) { 697 if (!leading_buttons_.empty() || !trailing_buttons_.empty()) {
703 observer->OnWindowButtonOrderingChange(leading_buttons_, trailing_buttons_); 698 observer->OnWindowButtonOrderingChange(leading_buttons_, trailing_buttons_);
704 } 699 }
705 700
706 observer_list_.AddObserver(observer); 701 window_button_order_observer_list_.AddObserver(observer);
707 } 702 }
708 703
709 void GtkUi::RemoveWindowButtonOrderObserver( 704 void GtkUi::RemoveWindowButtonOrderObserver(
710 views::WindowButtonOrderObserver* observer) { 705 views::WindowButtonOrderObserver* observer) {
711 observer_list_.RemoveObserver(observer); 706 window_button_order_observer_list_.RemoveObserver(observer);
712 } 707 }
713 708
714 void GtkUi::SetWindowButtonOrdering( 709 void GtkUi::SetWindowButtonOrdering(
715 const std::vector<views::FrameButton>& leading_buttons, 710 const std::vector<views::FrameButton>& leading_buttons,
716 const std::vector<views::FrameButton>& trailing_buttons) { 711 const std::vector<views::FrameButton>& trailing_buttons) {
717 leading_buttons_ = leading_buttons; 712 leading_buttons_ = leading_buttons;
718 trailing_buttons_ = trailing_buttons; 713 trailing_buttons_ = trailing_buttons;
719 714
720 for (views::WindowButtonOrderObserver& observer : observer_list_) 715 for (views::WindowButtonOrderObserver& observer :
716 window_button_order_observer_list_) {
721 observer.OnWindowButtonOrderingChange(leading_buttons_, trailing_buttons_); 717 observer.OnWindowButtonOrderingChange(leading_buttons_, trailing_buttons_);
718 }
722 } 719 }
723 720
724 void GtkUi::SetNonClientMiddleClickAction(NonClientMiddleClickAction action) { 721 void GtkUi::SetNonClientMiddleClickAction(NonClientMiddleClickAction action) {
725 middle_click_action_ = action; 722 middle_click_action_ = action;
726 } 723 }
727 724
728 std::unique_ptr<ui::LinuxInputMethodContext> GtkUi::CreateInputMethodContext( 725 std::unique_ptr<ui::LinuxInputMethodContext> GtkUi::CreateInputMethodContext(
729 ui::LinuxInputMethodContextDelegate* delegate, 726 ui::LinuxInputMethodContextDelegate* delegate,
730 bool is_simple) const { 727 bool is_simple) const {
731 return std::unique_ptr<ui::LinuxInputMethodContext>( 728 return std::unique_ptr<ui::LinuxInputMethodContext>(
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 GtkUi::GetNonClientMiddleClickAction() { 760 GtkUi::GetNonClientMiddleClickAction() {
764 return middle_click_action_; 761 return middle_click_action_;
765 } 762 }
766 763
767 void GtkUi::NotifyWindowManagerStartupComplete() { 764 void GtkUi::NotifyWindowManagerStartupComplete() {
768 // TODO(port) Implement this using _NET_STARTUP_INFO_BEGIN/_NET_STARTUP_INFO 765 // TODO(port) Implement this using _NET_STARTUP_INFO_BEGIN/_NET_STARTUP_INFO
769 // from http://standards.freedesktop.org/startup-notification-spec/ instead. 766 // from http://standards.freedesktop.org/startup-notification-spec/ instead.
770 gdk_notify_startup_complete(); 767 gdk_notify_startup_complete();
771 } 768 }
772 769
770 void GtkUi::AddDeviceScaleFactorObserver(
771 views::DeviceScaleFactorObserver* observer) {
772 device_scale_factor_observer_list_.AddObserver(observer);
773 }
774
775 void GtkUi::RemoveDeviceScaleFactorObserver(
776 views::DeviceScaleFactorObserver* observer) {
777 device_scale_factor_observer_list_.RemoveObserver(observer);
778 }
779
773 bool GtkUi::MatchEvent(const ui::Event& event, 780 bool GtkUi::MatchEvent(const ui::Event& event,
774 std::vector<ui::TextEditCommandAuraLinux>* commands) { 781 std::vector<ui::TextEditCommandAuraLinux>* commands) {
775 // Ensure that we have a keyboard handler. 782 // Ensure that we have a keyboard handler.
776 if (!key_bindings_handler_) 783 if (!key_bindings_handler_)
777 key_bindings_handler_.reset(new Gtk2KeyBindingsHandler); 784 key_bindings_handler_.reset(new Gtk2KeyBindingsHandler);
778 785
779 return key_bindings_handler_->MatchEvent(event, commands); 786 return key_bindings_handler_->MatchEvent(event, commands);
780 } 787 }
781 788
789 void GtkUi::OnDeviceScaleFactorMaybeChanged(void*, GParamSpec*) {
790 UpdateDeviceScaleFactor();
791 }
792
782 void GtkUi::SetScrollbarColors() { 793 void GtkUi::SetScrollbarColors() {
783 thumb_active_color_ = SkColorSetRGB(244, 244, 244); 794 thumb_active_color_ = SkColorSetRGB(244, 244, 244);
784 thumb_inactive_color_ = SkColorSetRGB(234, 234, 234); 795 thumb_inactive_color_ = SkColorSetRGB(234, 234, 234);
785 track_color_ = SkColorSetRGB(211, 211, 211); 796 track_color_ = SkColorSetRGB(211, 211, 211);
786 797
787 GetChromeStyleColor("scrollbar-slider-prelight-color", &thumb_active_color_); 798 GetChromeStyleColor("scrollbar-slider-prelight-color", &thumb_active_color_);
788 GetChromeStyleColor("scrollbar-slider-normal-color", &thumb_inactive_color_); 799 GetChromeStyleColor("scrollbar-slider-normal-color", &thumb_inactive_color_);
789 GetChromeStyleColor("scrollbar-trough-color", &track_color_); 800 GetChromeStyleColor("scrollbar-trough-color", &track_color_);
790 } 801 }
791 802
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 #endif 1041 #endif
1031 1042
1032 return false; 1043 return false;
1033 } 1044 }
1034 1045
1035 void GtkUi::ResetStyle() { 1046 void GtkUi::ResetStyle() {
1036 LoadGtkValues(); 1047 LoadGtkValues();
1037 native_theme_->NotifyObservers(); 1048 native_theme_->NotifyObservers();
1038 } 1049 }
1039 1050
1051 float GtkUi::GetRawDeviceScaleFactor() {
1052 if (display::Display::HasForceDeviceScaleFactor())
1053 return display::Display::GetForcedDeviceScaleFactor();
1054
1055 GdkScreen* screen = gdk_screen_get_default();
1056 gint scale = gtk_widget_get_scale_factor(fake_window_);
1057 gdouble resolution = gdk_screen_get_resolution(screen);
1058 const float scale_factor =
1059 resolution <= 0 ? scale : resolution * scale / kDefaultDPI;
1060 // Blacklist scaling factors <120% (crbug.com/484400) and round
1061 // to 1 decimal to prevent rendering problems (crbug.com/485183).
1062 return scale_factor < 1.2f ? 1.0f : roundf(scale_factor * 10) / 10;
1063 }
1064
1040 void GtkUi::UpdateDeviceScaleFactor() { 1065 void GtkUi::UpdateDeviceScaleFactor() {
1041 // Note: Linux chrome currently does not support dynamic DPI 1066 float old_device_scale_factor = device_scale_factor_;
1042 // changes. This is to allow flags to override the DPI settings
1043 // during startup.
1044 device_scale_factor_ = GetRawDeviceScaleFactor(); 1067 device_scale_factor_ = GetRawDeviceScaleFactor();
1068 if (device_scale_factor_ != old_device_scale_factor) {
1069 for (views::DeviceScaleFactorObserver& observer :
1070 device_scale_factor_observer_list_) {
1071 observer.OnDeviceScaleFactorChanged();
1072 }
1073 }
1045 UpdateDefaultFont(); 1074 UpdateDefaultFont();
1046 } 1075 }
1047 1076
1048 float GtkUi::GetDeviceScaleFactor() const { 1077 float GtkUi::GetDeviceScaleFactor() const {
1049 return device_scale_factor_; 1078 return device_scale_factor_;
1050 } 1079 }
1051 1080
1052 } // namespace libgtkui 1081 } // namespace libgtkui
1053 1082
1054 views::LinuxUI* BuildGtkUi() { 1083 views::LinuxUI* BuildGtkUi() {
1055 return new libgtkui::GtkUi; 1084 return new libgtkui::GtkUi;
1056 } 1085 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/libgtkui/gtk_ui.h ('k') | ui/views/linux_ui/device_scale_factor_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698