x_window_utils.cc 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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 "atom/browser/ui/x/x_window_utils.h"
  5. #include <X11/Xatom.h>
  6. #include <memory>
  7. #include "base/environment.h"
  8. #include "base/strings/string_util.h"
  9. #include "base/threading/thread_restrictions.h"
  10. #include "dbus/bus.h"
  11. #include "dbus/message.h"
  12. #include "dbus/object_proxy.h"
  13. #include "ui/base/x/x11_util.h"
  14. namespace atom {
  15. ::Atom GetAtom(const char* name) {
  16. return XInternAtom(gfx::GetXDisplay(), name, false);
  17. }
  18. void SetWMSpecState(::Window xwindow, bool enabled, ::Atom state) {
  19. XEvent xclient;
  20. memset(&xclient, 0, sizeof(xclient));
  21. xclient.type = ClientMessage;
  22. xclient.xclient.window = xwindow;
  23. xclient.xclient.message_type = GetAtom("_NET_WM_STATE");
  24. xclient.xclient.format = 32;
  25. xclient.xclient.data.l[0] = enabled ? 1 : 0;
  26. xclient.xclient.data.l[1] = state;
  27. xclient.xclient.data.l[2] = x11::None;
  28. xclient.xclient.data.l[3] = 1;
  29. xclient.xclient.data.l[4] = 0;
  30. XDisplay* xdisplay = gfx::GetXDisplay();
  31. XSendEvent(xdisplay, DefaultRootWindow(xdisplay), x11::False,
  32. SubstructureRedirectMask | SubstructureNotifyMask, &xclient);
  33. }
  34. void SetWindowType(::Window xwindow, const std::string& type) {
  35. XDisplay* xdisplay = gfx::GetXDisplay();
  36. std::string type_prefix = "_NET_WM_WINDOW_TYPE_";
  37. ::Atom window_type = XInternAtom(
  38. xdisplay, (type_prefix + base::ToUpperASCII(type)).c_str(), x11::False);
  39. XChangeProperty(xdisplay, xwindow,
  40. XInternAtom(xdisplay, "_NET_WM_WINDOW_TYPE", x11::False),
  41. XA_ATOM, 32, PropModeReplace,
  42. reinterpret_cast<unsigned char*>(&window_type), 1);
  43. }
  44. bool ShouldUseGlobalMenuBar() {
  45. base::ThreadRestrictions::ScopedAllowIO allow_io;
  46. std::unique_ptr<base::Environment> env(base::Environment::Create());
  47. if (env->HasVar("ELECTRON_FORCE_WINDOW_MENU_BAR"))
  48. return false;
  49. dbus::Bus::Options options;
  50. scoped_refptr<dbus::Bus> bus(new dbus::Bus(options));
  51. dbus::ObjectProxy* object_proxy =
  52. bus->GetObjectProxy(DBUS_SERVICE_DBUS, dbus::ObjectPath(DBUS_PATH_DBUS));
  53. dbus::MethodCall method_call(DBUS_INTERFACE_DBUS, "ListNames");
  54. std::unique_ptr<dbus::Response> response(object_proxy->CallMethodAndBlock(
  55. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
  56. if (!response) {
  57. bus->ShutdownAndBlock();
  58. return false;
  59. }
  60. dbus::MessageReader reader(response.get());
  61. dbus::MessageReader array_reader(NULL);
  62. if (!reader.PopArray(&array_reader)) {
  63. bus->ShutdownAndBlock();
  64. return false;
  65. }
  66. while (array_reader.HasMoreData()) {
  67. std::string name;
  68. if (array_reader.PopString(&name) &&
  69. name == "com.canonical.AppMenu.Registrar") {
  70. bus->ShutdownAndBlock();
  71. return true;
  72. }
  73. }
  74. bus->ShutdownAndBlock();
  75. return false;
  76. }
  77. void MoveWindowToForeground(::Window xwindow) {
  78. XDisplay* xdisplay = gfx::GetXDisplay();
  79. XEvent xclient;
  80. memset(&xclient, 0, sizeof(xclient));
  81. xclient.type = ClientMessage;
  82. xclient.xclient.display = xdisplay;
  83. xclient.xclient.window = xwindow;
  84. xclient.xclient.message_type = GetAtom("_NET_RESTACK_WINDOW");
  85. xclient.xclient.format = 32;
  86. xclient.xclient.data.l[0] = 2;
  87. xclient.xclient.data.l[1] = 0;
  88. xclient.xclient.data.l[2] = Above;
  89. xclient.xclient.data.l[3] = 0;
  90. xclient.xclient.data.l[4] = 0;
  91. XSendEvent(xdisplay, DefaultRootWindow(xdisplay), x11::False,
  92. SubstructureRedirectMask | SubstructureNotifyMask, &xclient);
  93. XFlush(xdisplay);
  94. }
  95. } // namespace atom