... |
... |
@@ -784,6 +784,53 @@ void nsWindow::ReparentNativeWidget(nsIWidget* aNewParent) { |
784
|
784
|
GtkWindowSetTransientFor(GTK_WINDOW(mShell), newParentWidget);
|
785
|
785
|
}
|
786
|
786
|
|
|
787
|
+static void InitPenEvent(WidgetMouseEvent& aGeckoEvent, GdkEvent* aEvent) {
|
|
788
|
+ // Find the source of the event
|
|
789
|
+ GdkDevice* device = gdk_event_get_source_device(aEvent);
|
|
790
|
+ GdkInputSource eSource = gdk_device_get_source(device);
|
|
791
|
+ gdouble value;
|
|
792
|
+
|
|
793
|
+ // We distinguish touch screens from pens using the event type
|
|
794
|
+ // Eraser corresponds to the pen with the "erase" button pressed
|
|
795
|
+ if (eSource != GDK_SOURCE_PEN && eSource != GDK_SOURCE_ERASER) {
|
|
796
|
+ bool XWaylandPen = false;
|
|
797
|
+#ifdef MOZ_X11
|
|
798
|
+ // Workaround : When using Xwayland, pens are reported as
|
|
799
|
+ // GDK_SOURCE_TOUCHSCREEN If eSource is GDK_SOURCE_TOUCHSCREEN and the
|
|
800
|
+ // GDK_AXIS_XTILT and GDK_AXIS_YTILT axes are reported then it's a pen and
|
|
801
|
+ // not a finger on a screen. Yes, that's a stupid heuristic but it works...
|
|
802
|
+ // Note, however, that the tilt values are not reliable
|
|
803
|
+ // Another approach could be use the device tool type, but that's only
|
|
804
|
+ // available in GTK > 3.22
|
|
805
|
+ XWaylandPen = (eSource == GDK_SOURCE_TOUCHSCREEN && GdkIsX11Display() &&
|
|
806
|
+ gdk_event_get_axis(aEvent, GDK_AXIS_XTILT, &value) &&
|
|
807
|
+ gdk_event_get_axis(aEvent, GDK_AXIS_YTILT, &value));
|
|
808
|
+#endif
|
|
809
|
+ if (!XWaylandPen) {
|
|
810
|
+ return;
|
|
811
|
+ }
|
|
812
|
+ LOGW("InitPenEvent(): Is XWayland pen");
|
|
813
|
+ }
|
|
814
|
+
|
|
815
|
+ aGeckoEvent.mInputSource = dom::MouseEvent_Binding::MOZ_SOURCE_PEN;
|
|
816
|
+ aGeckoEvent.pointerId = 1;
|
|
817
|
+
|
|
818
|
+ // The range of xtilt and ytilt are -1 to 1. Normalize it to -90 to 90.
|
|
819
|
+ if (gdk_event_get_axis(aEvent, GDK_AXIS_XTILT, &value)) {
|
|
820
|
+ aGeckoEvent.tiltX = int32_t(NS_round(value * 90));
|
|
821
|
+ }
|
|
822
|
+ if (gdk_event_get_axis(aEvent, GDK_AXIS_YTILT, &value)) {
|
|
823
|
+ aGeckoEvent.tiltY = int32_t(NS_round(value * 90));
|
|
824
|
+ }
|
|
825
|
+ if (gdk_event_get_axis(aEvent, GDK_AXIS_PRESSURE, &value)) {
|
|
826
|
+ aGeckoEvent.mPressure = (float)value;
|
|
827
|
+ // Make sure the pression is acceptable
|
|
828
|
+ MOZ_ASSERT(aGeckoEvent.mPressure >= 0.0 && aGeckoEvent.mPressure <= 1.0);
|
|
829
|
+ }
|
|
830
|
+
|
|
831
|
+ LOGW("InitPenEvent(): pressure %f\n", aGeckoEvent.mPressure);
|
|
832
|
+}
|
|
833
|
+
|
787
|
834
|
void nsWindow::SetModal(bool aModal) {
|
788
|
835
|
LOG("nsWindow::SetModal %d\n", aModal);
|
789
|
836
|
if (mIsDestroyed) {
|
... |
... |
@@ -4530,6 +4577,7 @@ void nsWindow::OnMotionNotifyEvent(GdkEventMotion* aEvent) { |
4530
|
4577
|
event.AssignEventTime(GetWidgetEventTime(aEvent->time));
|
4531
|
4578
|
|
4532
|
4579
|
KeymapWrapper::InitInputEvent(event, aEvent->state);
|
|
4580
|
+ InitPenEvent(event, (GdkEvent*)aEvent);
|
4533
|
4581
|
|
4534
|
4582
|
DispatchInputEvent(&event);
|
4535
|
4583
|
}
|
... |
... |
@@ -4806,6 +4854,7 @@ void nsWindow::OnButtonPressEvent(GdkEventButton* aEvent) { |
4806
|
4854
|
InitButtonEvent(event, aEvent, refPoint);
|
4807
|
4855
|
event.mPressure = mLastMotionPressure;
|
4808
|
4856
|
|
|
4857
|
+ InitPenEvent(event, (GdkEvent*)aEvent);
|
4809
|
4858
|
nsIWidget::ContentAndAPZEventStatus eventStatus = DispatchInputEvent(&event);
|
4810
|
4859
|
|
4811
|
4860
|
const bool defaultPrevented =
|
... |
... |
@@ -4875,6 +4924,8 @@ void nsWindow::OnButtonReleaseEvent(GdkEventButton* aEvent) { |
4875
|
4924
|
// to use it for the doubleclick position check.
|
4876
|
4925
|
const LayoutDeviceIntPoint pos = event.mRefPoint;
|
4877
|
4926
|
|
|
4927
|
+ InitPenEvent(event, (GdkEvent*)aEvent);
|
|
4928
|
+
|
4878
|
4929
|
nsIWidget::ContentAndAPZEventStatus eventStatus = DispatchInputEvent(&event);
|
4879
|
4930
|
|
4880
|
4931
|
const bool defaultPrevented =
|