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 "ui/views/widget/desktop_aura/x11_desktop_handler.h" | 5 #include "ui/views/widget/desktop_aura/x11_desktop_handler.h" |
6 | 6 |
7 #include <X11/Xatom.h> | 7 #include <X11/Xatom.h> |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 | 9 |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 ui::WmSupportsHint(atom_cache_.GetAtom("_NET_ACTIVE_WINDOW")); | 67 ui::WmSupportsHint(atom_cache_.GetAtom("_NET_ACTIVE_WINDOW")); |
68 } | 68 } |
69 } | 69 } |
70 | 70 |
71 X11DesktopHandler::~X11DesktopHandler() { | 71 X11DesktopHandler::~X11DesktopHandler() { |
72 aura::Env::GetInstance()->RemoveObserver(this); | 72 aura::Env::GetInstance()->RemoveObserver(this); |
73 if (ui::PlatformEventSource::GetInstance()) | 73 if (ui::PlatformEventSource::GetInstance()) |
74 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); | 74 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); |
75 } | 75 } |
76 | 76 |
77 void X11DesktopHandler::ActivateWindow(::Window window) { | 77 void X11DesktopHandler::ActivateWindow(::Window window, |
| 78 bool for_user_gesture) { |
78 if ((current_window_ == None || current_window_ == window) && | 79 if ((current_window_ == None || current_window_ == window) && |
79 current_window_active_state_ == NOT_ACTIVE) { | 80 current_window_active_state_ == NOT_ACTIVE) { |
80 // |window| is most likely still active wrt to the X server. Undo the | 81 // |window| is most likely still active wrt to the X server. Undo the |
81 // changes made in DeactivateWindow(). | 82 // changes made in DeactivateWindow(). |
82 OnActiveWindowChanged(window, ACTIVE); | 83 OnActiveWindowChanged(window, ACTIVE); |
83 | 84 |
84 // Go through the regular activation path such that calling | 85 // Go through the regular activation path such that calling |
85 // DeactivateWindow() and ActivateWindow() immediately afterwards results | 86 // DeactivateWindow() and ActivateWindow() immediately afterwards results |
86 // in an active X window. | 87 // in an active X window. |
87 } | 88 } |
88 | 89 |
89 XRaiseWindow(xdisplay_, window); | 90 XRaiseWindow(xdisplay_, window); |
90 | 91 |
91 if (wm_supports_active_window_) { | 92 if (wm_supports_active_window_) { |
92 DCHECK_EQ(gfx::GetXDisplay(), xdisplay_); | 93 DCHECK_EQ(gfx::GetXDisplay(), xdisplay_); |
93 | 94 |
| 95 // According to |
| 96 // http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#sourceindica
tion |
| 97 // "Some requests from Clients include type of the Client, for example the |
| 98 // _NET_ACTIVE_WINDOW message. Currently the types can be 1 for normal |
| 99 // applications, and 2 for pagers and other Clients that represent direct |
| 100 // user actions (the Window Manager may decide to treat requests from |
| 101 // applications differently than requests that are result of direct user |
| 102 // actions)." |
| 103 // |
| 104 // Normally we set the source indication to 1 (normal application), but when |
| 105 // we know activation is being triggered from a user gesture, then we set it |
| 106 // to 2 so the WM properly prioritizes our request. Without this, Unity on |
| 107 // Ubuntu 14.04 ignores requests to activate a window unless some other |
| 108 // Chrome window is already the active window (see issues 470830 & 411702). |
| 109 long source_indication = for_user_gesture ? 2 : 1; |
| 110 |
94 XEvent xclient; | 111 XEvent xclient; |
95 memset(&xclient, 0, sizeof(xclient)); | 112 memset(&xclient, 0, sizeof(xclient)); |
96 xclient.type = ClientMessage; | 113 xclient.type = ClientMessage; |
97 xclient.xclient.window = window; | 114 xclient.xclient.window = window; |
98 xclient.xclient.message_type = atom_cache_.GetAtom("_NET_ACTIVE_WINDOW"); | 115 xclient.xclient.message_type = atom_cache_.GetAtom("_NET_ACTIVE_WINDOW"); |
99 xclient.xclient.format = 32; | 116 xclient.xclient.format = 32; |
100 xclient.xclient.data.l[0] = 1; // Specified we are an app. | 117 xclient.xclient.data.l[0] = source_indication; |
101 xclient.xclient.data.l[1] = wm_user_time_ms_; | 118 xclient.xclient.data.l[1] = wm_user_time_ms_; |
102 xclient.xclient.data.l[2] = None; | 119 xclient.xclient.data.l[2] = None; |
103 xclient.xclient.data.l[3] = 0; | 120 xclient.xclient.data.l[3] = 0; |
104 xclient.xclient.data.l[4] = 0; | 121 xclient.xclient.data.l[4] = 0; |
105 | 122 |
106 XSendEvent(xdisplay_, x_root_window_, False, | 123 XSendEvent(xdisplay_, x_root_window_, False, |
107 SubstructureRedirectMask | SubstructureNotifyMask, | 124 SubstructureRedirectMask | SubstructureNotifyMask, |
108 &xclient); | 125 &xclient); |
109 } else { | 126 } else { |
110 // XRaiseWindow will not give input focus to the window. We now need to ask | 127 // XRaiseWindow will not give input focus to the window. We now need to ask |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 ui::XMenuList::GetInstance()->MaybeUnregisterMenu(window); | 258 ui::XMenuList::GetInstance()->MaybeUnregisterMenu(window); |
242 } | 259 } |
243 | 260 |
244 if (event_type == DestroyNotify) { | 261 if (event_type == DestroyNotify) { |
245 // Notify the XForeignWindowManager that |window| has been destroyed. | 262 // Notify the XForeignWindowManager that |window| has been destroyed. |
246 ui::XForeignWindowManager::GetInstance()->OnWindowDestroyed(window); | 263 ui::XForeignWindowManager::GetInstance()->OnWindowDestroyed(window); |
247 } | 264 } |
248 } | 265 } |
249 | 266 |
250 } // namespace views | 267 } // namespace views |
OLD | NEW |