settings_provider_gsettings.cc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ui/gtk/settings_provider_gsettings.h"
  5. #include <gio/gio.h>
  6. #include <memory>
  7. #include "base/environment.h"
  8. #include "base/nix/xdg_util.h"
  9. #include "ui/gtk/gtk_ui.h"
  10. #include "ui/gtk/gtk_util.h"
  11. namespace {
  12. const char kGnomePreferencesSchema[] = "org.gnome.desktop.wm.preferences";
  13. const char kCinnamonPreferencesSchema[] = "org.cinnamon.muffin";
  14. const char kButtonLayoutKey[] = "button-layout";
  15. const char kButtonLayoutChangedSignal[] = "changed::button-layout";
  16. const char kMiddleClickActionKey[] = "action-middle-click-titlebar";
  17. const char kMiddleClickActionChangedSignal[] =
  18. "changed::action-middle-click-titlebar";
  19. const char kDefaultButtonString[] = ":minimize,maximize,close";
  20. } // namespace
  21. namespace gtk {
  22. // Public interface:
  23. SettingsProviderGSettings::SettingsProviderGSettings(GtkUi* delegate)
  24. : delegate_(delegate) {
  25. DCHECK(delegate_);
  26. // Of all the supported distros, this code path should only be used by Ubuntu
  27. // 14.04 (all the others have a sufficient gtk version to use the GTK API).
  28. // The default in 14.04 is Unity, but Cinnamon has enough usage to justify
  29. // also checking its value.
  30. std::unique_ptr<base::Environment> env(base::Environment::Create());
  31. const gchar* settings_schema = base::nix::GetDesktopEnvironment(env.get()) ==
  32. base::nix::DESKTOP_ENVIRONMENT_CINNAMON
  33. ? kCinnamonPreferencesSchema
  34. : kGnomePreferencesSchema;
  35. GSettingsSchema* button_schema = g_settings_schema_source_lookup(
  36. g_settings_schema_source_get_default(), settings_schema, FALSE);
  37. if (!button_schema ||
  38. !g_settings_schema_has_key(button_schema, kButtonLayoutKey) ||
  39. !(button_settings_ = TakeGObject(g_settings_new(settings_schema)))) {
  40. ParseAndStoreButtonValue(kDefaultButtonString);
  41. } else {
  42. // Get the inital value of the keys we're interested in.
  43. OnDecorationButtonLayoutChanged(button_settings_, kButtonLayoutKey);
  44. signal_button_id_ = g_signal_connect(
  45. button_settings_, kButtonLayoutChangedSignal,
  46. G_CALLBACK(OnDecorationButtonLayoutChangedThunk), this);
  47. }
  48. GSettingsSchema* click_schema = g_settings_schema_source_lookup(
  49. g_settings_schema_source_get_default(), kGnomePreferencesSchema, FALSE);
  50. // If this fails, the default action has already been set in gtk_ui.cc.
  51. if (click_schema &&
  52. g_settings_schema_has_key(click_schema, kMiddleClickActionKey) &&
  53. (click_settings_ =
  54. TakeGObject(g_settings_new(kGnomePreferencesSchema)))) {
  55. OnMiddleClickActionChanged(click_settings_, kMiddleClickActionKey);
  56. signal_middle_click_id_ =
  57. g_signal_connect(click_settings_, kMiddleClickActionChangedSignal,
  58. G_CALLBACK(OnMiddleClickActionChangedThunk), this);
  59. }
  60. }
  61. SettingsProviderGSettings::~SettingsProviderGSettings() {
  62. if (signal_button_id_)
  63. g_signal_handler_disconnect(button_settings_, signal_button_id_);
  64. if (signal_middle_click_id_)
  65. g_signal_handler_disconnect(click_settings_, signal_middle_click_id_);
  66. }
  67. // Private:
  68. void SettingsProviderGSettings::OnDecorationButtonLayoutChanged(
  69. GSettings* settings,
  70. const gchar* key) {
  71. gchar* button_layout = g_settings_get_string(settings, kButtonLayoutKey);
  72. if (!button_layout)
  73. return;
  74. ParseAndStoreButtonValue(button_layout);
  75. g_free(button_layout);
  76. }
  77. void SettingsProviderGSettings::ParseAndStoreButtonValue(
  78. const std::string& button_string) {
  79. std::vector<views::FrameButton> leading_buttons;
  80. std::vector<views::FrameButton> trailing_buttons;
  81. ParseButtonLayout(button_string, &leading_buttons, &trailing_buttons);
  82. delegate_->SetWindowButtonOrdering(leading_buttons, trailing_buttons);
  83. }
  84. void SettingsProviderGSettings::OnMiddleClickActionChanged(GSettings* settings,
  85. const gchar* key) {
  86. gchar* click_action = g_settings_get_string(settings, kMiddleClickActionKey);
  87. if (!click_action)
  88. return;
  89. ParseAndStoreMiddleClickValue(click_action);
  90. g_free(click_action);
  91. }
  92. void SettingsProviderGSettings::ParseAndStoreMiddleClickValue(
  93. const std::string& click_action) {
  94. GtkUi::WindowFrameAction action;
  95. if (click_action == "none") {
  96. action = ui::LinuxUi::WindowFrameAction::kNone;
  97. } else if (click_action == "lower") {
  98. action = ui::LinuxUi::WindowFrameAction::kLower;
  99. } else if (click_action == "minimize") {
  100. action = ui::LinuxUi::WindowFrameAction::kMinimize;
  101. } else if (click_action == "toggle-maximize") {
  102. action = ui::LinuxUi::WindowFrameAction::kToggleMaximize;
  103. } else {
  104. // While we want to have the default state be lower if there isn't a
  105. // value, we want to default to no action if the user has explicitly
  106. // chose an action that we don't implement.
  107. action = ui::LinuxUi::WindowFrameAction::kNone;
  108. }
  109. delegate_->SetWindowFrameAction(
  110. ui::LinuxUi::WindowFrameActionSource::kMiddleClick, action);
  111. }
  112. } // namespace gtk