fix mouse jumping: query GDK pointer position at call time
Flutter's globalPosition is window-relative, not screen-absolute. Now using gdk_device_get_position() on the native side to get the actual screen coordinates at the moment startDrag/startResize is called. Dart no longer passes coordinates — the native handler queries the pointer directly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -221,7 +221,7 @@ class _HatBar extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final tokens = ClideTheme.of(context).surface;
|
final tokens = ClideTheme.of(context).surface;
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onPanStart: (d) => kernel.window.startDrag(d.globalPosition),
|
onPanStart: (_) => kernel.window.startDrag(),
|
||||||
child: Container(
|
child: Container(
|
||||||
height: hatHeight,
|
height: hatHeight,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
|||||||
@@ -17,24 +17,17 @@ class WindowControls extends ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> startResize(ResizeEdge edge, Offset screenPosition) async {
|
Future<void> startResize(ResizeEdge edge) async {
|
||||||
try {
|
try {
|
||||||
await _channel.invokeMethod('startResize', {
|
await _channel.invokeMethod('startResize', edge.index);
|
||||||
'edge': edge.index,
|
|
||||||
'x': screenPosition.dx.round(),
|
|
||||||
'y': screenPosition.dy.round(),
|
|
||||||
});
|
|
||||||
} on MissingPluginException {
|
} on MissingPluginException {
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> startDrag(Offset screenPosition) async {
|
Future<void> startDrag() async {
|
||||||
try {
|
try {
|
||||||
await _channel.invokeMethod('startDrag', {
|
await _channel.invokeMethod('startDrag');
|
||||||
'x': screenPosition.dx.round(),
|
|
||||||
'y': screenPosition.dy.round(),
|
|
||||||
});
|
|
||||||
} on MissingPluginException {
|
} on MissingPluginException {
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class ColumnHat extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final tokens = ClideTheme.of(context).surface;
|
final tokens = ClideTheme.of(context).surface;
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onPanStart: (d) => windowControls.startDrag(d.globalPosition),
|
onPanStart: (_) => windowControls.startDrag(),
|
||||||
child: Container(
|
child: Container(
|
||||||
height: hatHeight,
|
height: hatHeight,
|
||||||
color: tokens.panelHeader,
|
color: tokens.panelHeader,
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class ClideResizeBorder extends StatelessWidget {
|
|||||||
return MouseRegion(
|
return MouseRegion(
|
||||||
cursor: cursor,
|
cursor: cursor,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onPanStart: (d) => windowControls.startResize(edge, d.globalPosition),
|
onPanStart: (_) => windowControls.startResize(edge),
|
||||||
child: const ColoredBox(color: Color(0x00000000)),
|
child: const ColoredBox(color: Color(0x00000000)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -157,28 +157,28 @@ static void my_application_activate(GApplication* application) {
|
|||||||
g_autoptr(FlMethodResponse) response = nullptr;
|
g_autoptr(FlMethodResponse) response = nullptr;
|
||||||
|
|
||||||
if (g_strcmp0(method, "startDrag") == 0) {
|
if (g_strcmp0(method, "startDrag") == 0) {
|
||||||
FlValue* args = fl_method_call_get_args(method_call);
|
GdkDisplay* display = gtk_widget_get_display(GTK_WIDGET(w));
|
||||||
int x = 0, y = 0;
|
GdkSeat* seat = gdk_display_get_default_seat(display);
|
||||||
if (fl_value_get_type(args) == FL_VALUE_TYPE_MAP) {
|
GdkDevice* pointer = gdk_seat_get_pointer(seat);
|
||||||
FlValue* vx = fl_value_lookup_string(args, "x");
|
gint x = 0, y = 0;
|
||||||
FlValue* vy = fl_value_lookup_string(args, "y");
|
gdk_device_get_position(pointer, nullptr, &x, &y);
|
||||||
if (vx) x = (int)fl_value_get_int(vx);
|
|
||||||
if (vy) y = (int)fl_value_get_int(vy);
|
|
||||||
}
|
|
||||||
gtk_window_begin_move_drag(w, 1, x, y, GDK_CURRENT_TIME);
|
gtk_window_begin_move_drag(w, 1, x, y, GDK_CURRENT_TIME);
|
||||||
response = FL_METHOD_RESPONSE(
|
response = FL_METHOD_RESPONSE(
|
||||||
fl_method_success_response_new(fl_value_new_null()));
|
fl_method_success_response_new(fl_value_new_null()));
|
||||||
} else if (g_strcmp0(method, "startResize") == 0) {
|
} else if (g_strcmp0(method, "startResize") == 0) {
|
||||||
FlValue* args = fl_method_call_get_args(method_call);
|
FlValue* args = fl_method_call_get_args(method_call);
|
||||||
int edge = 7, x = 0, y = 0;
|
int edge = 7;
|
||||||
if (fl_value_get_type(args) == FL_VALUE_TYPE_MAP) {
|
if (fl_value_get_type(args) == FL_VALUE_TYPE_MAP) {
|
||||||
FlValue* ve = fl_value_lookup_string(args, "edge");
|
FlValue* ve = fl_value_lookup_string(args, "edge");
|
||||||
FlValue* vx = fl_value_lookup_string(args, "x");
|
|
||||||
FlValue* vy = fl_value_lookup_string(args, "y");
|
|
||||||
if (ve) edge = (int)fl_value_get_int(ve);
|
if (ve) edge = (int)fl_value_get_int(ve);
|
||||||
if (vx) x = (int)fl_value_get_int(vx);
|
} else if (fl_value_get_type(args) == FL_VALUE_TYPE_INT) {
|
||||||
if (vy) y = (int)fl_value_get_int(vy);
|
edge = (int)fl_value_get_int(args);
|
||||||
}
|
}
|
||||||
|
GdkDisplay* display = gtk_widget_get_display(GTK_WIDGET(w));
|
||||||
|
GdkSeat* seat = gdk_display_get_default_seat(display);
|
||||||
|
GdkDevice* pointer = gdk_seat_get_pointer(seat);
|
||||||
|
gint x = 0, y = 0;
|
||||||
|
gdk_device_get_position(pointer, nullptr, &x, &y);
|
||||||
static const GdkWindowEdge edges[] = {
|
static const GdkWindowEdge edges[] = {
|
||||||
GDK_WINDOW_EDGE_NORTH_WEST, GDK_WINDOW_EDGE_NORTH,
|
GDK_WINDOW_EDGE_NORTH_WEST, GDK_WINDOW_EDGE_NORTH,
|
||||||
GDK_WINDOW_EDGE_NORTH_EAST, GDK_WINDOW_EDGE_WEST,
|
GDK_WINDOW_EDGE_NORTH_EAST, GDK_WINDOW_EDGE_WEST,
|
||||||
|
|||||||
Reference in New Issue
Block a user