x_window_utils.cc 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Copyright (c) 2014 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "shell/browser/ui/x/x_window_utils.h"
  5. #include <memory>
  6. #include "base/environment.h"
  7. #include "base/strings/string_util.h"
  8. #include "dbus/bus.h"
  9. #include "dbus/message.h"
  10. #include "dbus/object_proxy.h"
  11. #include "shell/common/thread_restrictions.h"
  12. #include "ui/base/x/x11_util.h"
  13. #include "ui/gfx/x/atom_cache.h"
  14. #include "ui/gfx/x/connection.h"
  15. #include "ui/gfx/x/xproto.h"
  16. namespace electron {
  17. void SetWindowType(x11::Window window, const std::string& type) {
  18. std::string type_prefix = "_NET_WM_WINDOW_TYPE_";
  19. std::string window_type_str = type_prefix + base::ToUpperASCII(type);
  20. x11::Atom window_type = x11::GetAtom(window_type_str.c_str());
  21. auto* connection = x11::Connection::Get();
  22. connection->SetProperty(window, x11::GetAtom("_NET_WM_WINDOW_TYPE"),
  23. x11::Atom::ATOM, window_type);
  24. }
  25. bool ShouldUseGlobalMenuBar() {
  26. ScopedAllowBlockingForElectron allow_blocking;
  27. auto env = base::Environment::Create();
  28. if (env->HasVar("ELECTRON_FORCE_WINDOW_MENU_BAR"))
  29. return false;
  30. dbus::Bus::Options options;
  31. auto bus = base::MakeRefCounted<dbus::Bus>(options);
  32. dbus::ObjectProxy* object_proxy =
  33. bus->GetObjectProxy(DBUS_SERVICE_DBUS, dbus::ObjectPath(DBUS_PATH_DBUS));
  34. dbus::MethodCall method_call(DBUS_INTERFACE_DBUS, "ListNames");
  35. std::unique_ptr<dbus::Response> response =
  36. object_proxy
  37. ->CallMethodAndBlock(&method_call,
  38. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)
  39. .value_or(nullptr);
  40. if (!response) {
  41. bus->ShutdownAndBlock();
  42. return false;
  43. }
  44. dbus::MessageReader reader(response.get());
  45. dbus::MessageReader array_reader(nullptr);
  46. if (!reader.PopArray(&array_reader)) {
  47. bus->ShutdownAndBlock();
  48. return false;
  49. }
  50. while (array_reader.HasMoreData()) {
  51. std::string name;
  52. if (array_reader.PopString(&name) &&
  53. name == "com.canonical.AppMenu.Registrar") {
  54. bus->ShutdownAndBlock();
  55. return true;
  56. }
  57. }
  58. bus->ShutdownAndBlock();
  59. return false;
  60. }
  61. void MoveWindowToForeground(x11::Window window) {
  62. MoveWindowAbove(window, static_cast<x11::Window>(0));
  63. }
  64. void MoveWindowAbove(x11::Window window, x11::Window other_window) {
  65. ui::SendClientMessage(window, ui::GetX11RootWindow(),
  66. x11::GetAtom("_NET_RESTACK_WINDOW"),
  67. {2, static_cast<uint32_t>(other_window),
  68. static_cast<uint32_t>(x11::StackMode::Above), 0, 0});
  69. }
  70. bool IsWindowValid(x11::Window window) {
  71. auto* conn = x11::Connection::Get();
  72. return conn->GetWindowAttributes({window}).Sync();
  73. }
  74. } // namespace electron