|
1 |
|
2 # HG changeset patch |
|
3 # User Robin Grenet <robin.grenet@wanadoo.fr> |
|
4 # Date 1510835758 -3600 |
|
5 # Node ID f540f9e801cb2e0be5259baea13dfce953ccb520 |
|
6 # Parent 0abbf75bd0ecfa99ab4386f551a622983f5f27ea |
|
7 Bug 1360278 - Add preference to trigger context menu on mouse up for GTK+ and macOS, r=mstange,smaug |
|
8 |
|
9 MozReview-Commit-ID: Bg60bD8jIg6 |
|
10 |
|
11 diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js |
|
12 --- a/modules/libpref/init/all.js |
|
13 +++ b/modules/libpref/init/all.js |
|
14 @@ -229,16 +229,20 @@ pref("dom.script_loader.bytecode_cache.e |
|
15 pref("dom.script_loader.bytecode_cache.strategy", 0); |
|
16 |
|
17 // Fastback caching - if this pref is negative, then we calculate the number |
|
18 // of content viewers to cache based on the amount of available memory. |
|
19 pref("browser.sessionhistory.max_total_viewers", -1); |
|
20 |
|
21 pref("ui.use_native_colors", true); |
|
22 pref("ui.click_hold_context_menus", false); |
|
23 + |
|
24 +// Pop up context menu on mouseup instead of mousedown, if that's the OS default. |
|
25 +// Note: ignored on Windows (context menus always use mouseup) |
|
26 +pref("ui.context_menus.after_mouseup", false); |
|
27 // Duration of timeout of incremental search in menus (ms). 0 means infinite. |
|
28 pref("ui.menu.incremental_search.timeout", 1000); |
|
29 // If true, all popups won't hide automatically on blur |
|
30 pref("ui.popup.disable_autohide", false); |
|
31 |
|
32 pref("browser.display.use_document_fonts", 1); // 0 = never, 1 = quick, 2 = always |
|
33 // 0 = default: always, except in high contrast mode |
|
34 // 1 = always |
|
35 diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm |
|
36 --- a/widget/cocoa/nsChildView.mm |
|
37 +++ b/widget/cocoa/nsChildView.mm |
|
38 @@ -4695,18 +4695,20 @@ NSEvent* gLastDragMouseDownEvent = nil; |
|
39 [self convertCocoaMouseEvent:theEvent toGeckoEvent:&geckoEvent]; |
|
40 geckoEvent.button = WidgetMouseEvent::eRightButton; |
|
41 geckoEvent.mClickCount = [theEvent clickCount]; |
|
42 |
|
43 mGeckoChild->DispatchInputEvent(&geckoEvent); |
|
44 if (!mGeckoChild) |
|
45 return; |
|
46 |
|
47 - // Let the superclass do the context menu stuff. |
|
48 - [super rightMouseDown:theEvent]; |
|
49 + if (!nsBaseWidget::ShowContextMenuAfterMouseUp()) { |
|
50 + // Let the superclass do the context menu stuff. |
|
51 + [super rightMouseDown:theEvent]; |
|
52 + } |
|
53 |
|
54 NS_OBJC_END_TRY_ABORT_BLOCK; |
|
55 } |
|
56 |
|
57 - (void)rightMouseUp:(NSEvent *)theEvent |
|
58 { |
|
59 NS_OBJC_BEGIN_TRY_ABORT_BLOCK; |
|
60 |
|
61 @@ -4719,16 +4721,33 @@ NSEvent* gLastDragMouseDownEvent = nil; |
|
62 WidgetMouseEvent geckoEvent(true, eMouseUp, mGeckoChild, |
|
63 WidgetMouseEvent::eReal); |
|
64 [self convertCocoaMouseEvent:theEvent toGeckoEvent:&geckoEvent]; |
|
65 geckoEvent.button = WidgetMouseEvent::eRightButton; |
|
66 geckoEvent.mClickCount = [theEvent clickCount]; |
|
67 |
|
68 nsAutoRetainCocoaObject kungFuDeathGrip(self); |
|
69 mGeckoChild->DispatchInputEvent(&geckoEvent); |
|
70 + if (!mGeckoChild) |
|
71 + return; |
|
72 + |
|
73 + if (nsBaseWidget::ShowContextMenuAfterMouseUp()) { |
|
74 + // Let the superclass do the context menu stuff, but pretend it's rightMouseDown. |
|
75 + NSEvent *dupeEvent = [NSEvent mouseEventWithType:NSRightMouseDown |
|
76 + location:theEvent.locationInWindow |
|
77 + modifierFlags:theEvent.modifierFlags |
|
78 + timestamp:theEvent.timestamp |
|
79 + windowNumber:theEvent.windowNumber |
|
80 + context:theEvent.context |
|
81 + eventNumber:theEvent.eventNumber |
|
82 + clickCount:theEvent.clickCount |
|
83 + pressure:theEvent.pressure]; |
|
84 + |
|
85 + [super rightMouseDown:dupeEvent]; |
|
86 + } |
|
87 |
|
88 NS_OBJC_END_TRY_ABORT_BLOCK; |
|
89 } |
|
90 |
|
91 - (void)rightMouseDragged:(NSEvent*)theEvent |
|
92 { |
|
93 if (!mGeckoChild) |
|
94 return; |
|
95 diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp |
|
96 --- a/widget/gtk/nsWindow.cpp |
|
97 +++ b/widget/gtk/nsWindow.cpp |
|
98 @@ -2733,16 +2733,29 @@ nsWindow::InitButtonEvent(WidgetMouseEve |
|
99 } |
|
100 |
|
101 static guint ButtonMaskFromGDKButton(guint button) |
|
102 { |
|
103 return GDK_BUTTON1_MASK << (button - 1); |
|
104 } |
|
105 |
|
106 void |
|
107 +nsWindow::DispatchContextMenuEventFromMouseEvent(uint16_t domButton, |
|
108 + GdkEventButton *aEvent) |
|
109 +{ |
|
110 + if (domButton == WidgetMouseEvent::eRightButton && MOZ_LIKELY(!mIsDestroyed)) { |
|
111 + WidgetMouseEvent contextMenuEvent(true, eContextMenu, this, |
|
112 + WidgetMouseEvent::eReal); |
|
113 + InitButtonEvent(contextMenuEvent, aEvent); |
|
114 + contextMenuEvent.pressure = mLastMotionPressure; |
|
115 + DispatchInputEvent(&contextMenuEvent); |
|
116 + } |
|
117 +} |
|
118 + |
|
119 +void |
|
120 nsWindow::OnButtonPressEvent(GdkEventButton *aEvent) |
|
121 { |
|
122 LOG(("Button %u press on %p\n", aEvent->button, (void *)this)); |
|
123 |
|
124 // If you double click in GDK, it will actually generate a second |
|
125 // GDK_BUTTON_PRESS before sending the GDK_2BUTTON_PRESS, and this is |
|
126 // different than the DOM spec. GDK puts this in the queue |
|
127 // programatically, so it's safe to assume that if there's a |
|
128 @@ -2801,23 +2814,18 @@ nsWindow::OnButtonPressEvent(GdkEventBut |
|
129 WidgetMouseEvent event(true, eMouseDown, this, WidgetMouseEvent::eReal); |
|
130 event.button = domButton; |
|
131 InitButtonEvent(event, aEvent); |
|
132 event.pressure = mLastMotionPressure; |
|
133 |
|
134 DispatchInputEvent(&event); |
|
135 |
|
136 // right menu click on linux should also pop up a context menu |
|
137 - if (domButton == WidgetMouseEvent::eRightButton && |
|
138 - MOZ_LIKELY(!mIsDestroyed)) { |
|
139 - WidgetMouseEvent contextMenuEvent(true, eContextMenu, this, |
|
140 - WidgetMouseEvent::eReal); |
|
141 - InitButtonEvent(contextMenuEvent, aEvent); |
|
142 - contextMenuEvent.pressure = mLastMotionPressure; |
|
143 - DispatchInputEvent(&contextMenuEvent); |
|
144 + if (!nsBaseWidget::ShowContextMenuAfterMouseUp()) { |
|
145 + DispatchContextMenuEventFromMouseEvent(domButton, aEvent); |
|
146 } |
|
147 } |
|
148 |
|
149 void |
|
150 nsWindow::OnButtonReleaseEvent(GdkEventButton *aEvent) |
|
151 { |
|
152 LOG(("Button %u release on %p\n", aEvent->button, (void *)this)); |
|
153 |
|
154 @@ -2843,16 +2851,21 @@ nsWindow::OnButtonReleaseEvent(GdkEventB |
|
155 event.button = domButton; |
|
156 InitButtonEvent(event, aEvent); |
|
157 gdouble pressure = 0; |
|
158 gdk_event_get_axis ((GdkEvent*)aEvent, GDK_AXIS_PRESSURE, &pressure); |
|
159 event.pressure = pressure ? pressure : mLastMotionPressure; |
|
160 |
|
161 DispatchInputEvent(&event); |
|
162 mLastMotionPressure = pressure; |
|
163 + |
|
164 + // right menu click on linux should also pop up a context menu |
|
165 + if (nsBaseWidget::ShowContextMenuAfterMouseUp()) { |
|
166 + DispatchContextMenuEventFromMouseEvent(domButton, aEvent); |
|
167 + } |
|
168 } |
|
169 |
|
170 void |
|
171 nsWindow::OnContainerFocusInEvent(GdkEventFocus *aEvent) |
|
172 { |
|
173 LOGFOCUS(("OnContainerFocusInEvent [%p]\n", (void *)this)); |
|
174 |
|
175 // Unset the urgency hint, if possible |
|
176 diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h |
|
177 --- a/widget/gtk/nsWindow.h |
|
178 +++ b/widget/gtk/nsWindow.h |
|
179 @@ -240,16 +240,18 @@ private: |
|
180 LayoutDeviceIntSize GetSafeWindowSize(LayoutDeviceIntSize aSize); |
|
181 |
|
182 void EnsureGrabs (void); |
|
183 void GrabPointer (guint32 aTime); |
|
184 void ReleaseGrabs (void); |
|
185 |
|
186 void UpdateClientOffset(); |
|
187 |
|
188 + void DispatchContextMenuEventFromMouseEvent(uint16_t domButton, |
|
189 + GdkEventButton *aEvent); |
|
190 public: |
|
191 void ThemeChanged(void); |
|
192 void OnDPIChanged(void); |
|
193 void OnCheckResize(void); |
|
194 void OnCompositedChanged(void); |
|
195 |
|
196 #ifdef MOZ_X11 |
|
197 Window mOldFocusWindow; |
|
198 diff --git a/widget/nsBaseWidget.cpp b/widget/nsBaseWidget.cpp |
|
199 --- a/widget/nsBaseWidget.cpp |
|
200 +++ b/widget/nsBaseWidget.cpp |
|
201 @@ -1213,16 +1213,32 @@ nsBaseWidget::DispatchEventToAPZOnly(moz |
|
202 if (mAPZC) { |
|
203 MOZ_ASSERT(APZThreadUtils::IsControllerThread()); |
|
204 uint64_t inputBlockId = 0; |
|
205 ScrollableLayerGuid guid; |
|
206 mAPZC->ReceiveInputEvent(*aEvent, &guid, &inputBlockId); |
|
207 } |
|
208 } |
|
209 |
|
210 +// static |
|
211 +bool |
|
212 +nsBaseWidget::ShowContextMenuAfterMouseUp() |
|
213 +{ |
|
214 + static bool gContextMenuAfterMouseUp = false; |
|
215 + static bool gContextMenuAfterMouseUpCached = false; |
|
216 + if (!gContextMenuAfterMouseUpCached) { |
|
217 + Preferences::AddBoolVarCache(&gContextMenuAfterMouseUp, |
|
218 + "ui.context_menus.after_mouseup", |
|
219 + false); |
|
220 + |
|
221 + gContextMenuAfterMouseUpCached = true; |
|
222 + } |
|
223 + return gContextMenuAfterMouseUp; |
|
224 +} |
|
225 + |
|
226 nsIDocument* |
|
227 nsBaseWidget::GetDocument() const |
|
228 { |
|
229 if (mWidgetListener) { |
|
230 if (nsIPresShell* presShell = mWidgetListener->GetPresShell()) { |
|
231 return presShell->GetDocument(); |
|
232 } |
|
233 } |
|
234 diff --git a/widget/nsBaseWidget.h b/widget/nsBaseWidget.h |
|
235 --- a/widget/nsBaseWidget.h |
|
236 +++ b/widget/nsBaseWidget.h |
|
237 @@ -412,16 +412,22 @@ public: |
|
238 void NotifyLiveResizeStopped(); |
|
239 |
|
240 #if defined(MOZ_WIDGET_ANDROID) |
|
241 void RecvToolbarAnimatorMessageFromCompositor(int32_t) override {}; |
|
242 void UpdateRootFrameMetrics(const ScreenPoint& aScrollOffset, const CSSToScreenScale& aZoom) override {}; |
|
243 void RecvScreenPixels(mozilla::ipc::Shmem&& aMem, const ScreenIntSize& aSize) override {}; |
|
244 #endif |
|
245 |
|
246 + /** |
|
247 + * Whether context menus should only appear on mouseup instead of mousedown, |
|
248 + * on OSes where they normally appear on mousedown (macOS, *nix). |
|
249 + */ |
|
250 + static bool ShowContextMenuAfterMouseUp(); |
|
251 + |
|
252 protected: |
|
253 // These are methods for CompositorWidgetWrapper, and should only be |
|
254 // accessed from that class. Derived widgets can choose which methods to |
|
255 // implement, or none if supporting out-of-process compositing. |
|
256 virtual bool PreRender(mozilla::widget::WidgetRenderingContext* aContext) { |
|
257 return true; |
|
258 } |
|
259 virtual void PostRender(mozilla::widget::WidgetRenderingContext* aContext) |
|
260 |