flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
165.72k stars 27.37k forks source link

`Slider::onChanged` fires twice after window is resized horizontally. #112290

Open a-wallen opened 2 years ago

a-wallen commented 2 years ago

https://user-images.githubusercontent.com/44445638/192026531-6aff356a-78c1-4591-91c8-2425ca62a179.mov

Behavior works as expected for the vertical slider, but not the horizontal one. Instead of dragging, I am tapping the slider for clarity.

Steps to Reproduce

I suppose this will work for any platform, but I am running a macos app.

Expected results: Horizontal slider resizes the window like the vertical slider

Actual results: Horizontal slider resizes to the maximum value every time

MainFlutterWindow.swift ```swift // Copyright 2014 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import Cocoa import FlutterMacOS extension NSWindow { var titlebarHeight: CGFloat { frame.height - contentRect(forFrameRect: frame).height } } class MainFlutterWindow: NSWindow { override func awakeFromNib() { let flutterViewController = FlutterViewController.init() let windowFrame = self.frame self.contentViewController = flutterViewController self.setFrame(windowFrame, display: true) RegisterMethodChannel(registry: flutterViewController) RegisterGeneratedPlugins(registry: flutterViewController) super.awakeFromNib() } func RegisterMethodChannel(registry: FlutterPluginRegistry) { let registrar = registry.registrar(forPlugin: "resize") let channel = FlutterMethodChannel(name: "samples.flutter.dev/resize", binaryMessenger: registrar.messenger) channel.setMethodCallHandler({ (call, result) in if call.method == "resize" { if let args = call.arguments as? Dictionary, let width = args["width"] as? Double, var height = args["height"] as? Double { height += self.titlebarHeight let currentFrame: NSRect = self.frame let nextFrame: NSRect = NSMakeRect( currentFrame.minX - (width - currentFrame.width) / 2, currentFrame.minY - (height - currentFrame.height) / 2, width, height ) self.setFrame(nextFrame, display: true, animate: false) result(true) } else { result(FlutterError.init(code: "bad args", message: nil, details: nil)) } } else if call.method == "get bounds" { let bounds: NSRect = self.screen!.frame result([ "x": bounds.width, "y": bounds.height, ]) } }) } } ```
main.dart ```dart // Copyright 2014 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() async { runApp(const ResizeApp()); } class ResizeApp extends StatefulWidget { const ResizeApp({super.key}); static const MethodChannel platform = MethodChannel('samples.flutter.dev/resize'); static const Key heightLabel = Key('height label'); static const Key widthLabel = Key('width label'); static const Key heightSlider = Key('height slider'); static const Key widthSlider = Key('width slider'); static const Size constraints = Size(150, 150); Future resize(Size size) async { await ResizeApp.platform.invokeMethod( 'resize', { 'width': size.width, 'height': size.height, } ); } Future get bounds async { final Map? result = await ResizeApp.platform.invokeMapMethod('get bounds'); if ( result == null || result['x'] == null || result['y'] == null ) { throw const FormatException('Platform channel "get bounds" gave an invalid argument.'); } return Size(result['x']!, result['y']!); } @override State createState() => _ResizeAppState(); } class _ResizeAppState extends State { Size? _bounds; Future get bounds async { if(_bounds != null) { return _bounds!; } _bounds = await widget.bounds; return _bounds!; } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Center( child: SizedBox( height: ResizeApp.constraints.height, width: ResizeApp.constraints.width, child: FutureBuilder( future: bounds, builder: (BuildContext context, AsyncSnapshot snapshot) { if(!snapshot.hasData) { return const CircularProgressIndicator(); } final Size currentSize = MediaQuery.of(context).size; return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( key: ResizeApp.widthLabel, 'width: ${currentSize.width}' ), Slider( key: ResizeApp.widthSlider, value: currentSize.width, max: snapshot.data!.width, onChanged: (double value) { final Size nextSize = Size( value.clamp(ResizeApp.constraints.width, snapshot.data!.width), currentSize.height, ); widget.resize(nextSize); }, ), Text( key: ResizeApp.heightLabel, 'height: ${currentSize.height}' ), Slider( key: ResizeApp.heightSlider, value: currentSize.height, max: snapshot.data!.height, onChanged: (double value) { print(value); final Size nextSize = Size( currentSize.width, value.clamp(ResizeApp.constraints.height, snapshot.data!.height), ); widget.resize(nextSize); }, ), ], ); }, ), ), ), ) ); } } ```
danagbemava-nc commented 2 years ago

Issue is reproducible using the code sample provided above.

https://user-images.githubusercontent.com/88313112/192232825-7810bcb8-4c88-4cd5-a313-6f1e98aa1a5b.mov

flutter doctor -v ``` [✓] Flutter (Channel stable, 3.3.2, on macOS 12.6 21G115 darwin-arm, locale en-GB) • Flutter version 3.3.2 on channel stable at /Users/nexus/dev/sdks/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision e3c29ec00c (12 days ago), 2022-09-14 08:46:55 -0500 • Engine revision a4ff2c53d8 • Dart version 2.18.1 • DevTools version 2.15.0 [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0) • Android SDK at /Users/nexus/Library/Android/sdk • Platform android-33, build-tools 33.0.0 • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 14.0) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 14A309 • CocoaPods version 1.11.3 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2021.3) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866) [✓] Android Studio (version 2021.2) • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/212.5712.43.2112.8815526/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840) [✓] VS Code (version 1.71.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.48.0 [✓] Connected device (4 available) • Nexus (mobile) • 00008020-001875E83A38002E • ios • iOS 16.0.2 20A380 • iPhone 14 Pro (mobile) • 4302007A-B132-4B89-887A-C5993FCA3284 • ios • com.apple.CoreSimulator.SimRuntime.iOS-16-0 (simulator) • macOS (desktop) • macos • darwin-arm64 • macOS 12.6 21G115 darwin-arm • Chrome (web) • chrome • web-javascript • Google Chrome 105.0.5195.125 [✓] HTTP Host Availability • All required HTTP hosts are available • No issues found! ``` ``` [✓] Flutter (Channel master, 3.4.0-30.0.pre.18, on macOS 12.6 21G115 darwin-arm64, locale en-GB) • Flutter version 3.4.0-30.0.pre.18 on channel master at /Users/nexus/dev/sdks/flutters • Upstream repository https://github.com/flutter/flutter.git • Framework revision 9f5174f721 (7 hours ago), 2022-09-25 21:14:31 -0400 • Engine revision 1c232b584c • Dart version 2.19.0 (build 2.19.0-240.0.dev) • DevTools version 2.17.0 [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0) • Android SDK at /Users/nexus/Library/Android/sdk • Platform android-33, build-tools 33.0.0 • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 14.0) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 14A309 • CocoaPods version 1.11.3 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2021.3) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866) [✓] Android Studio (version 2021.2) • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/212.5712.43.2112.8815526/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840) [✓] VS Code (version 1.71.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.48.0 [✓] Connected device (4 available) • Nexus (mobile) • 00008020-001875E83A38002E • ios • iOS 16.0.2 20A380 • iPhone 14 Pro (mobile) • 4302007A-B132-4B89-887A-C5993FCA3284 • ios • com.apple.CoreSimulator.SimRuntime.iOS-16-0 (simulator) • macOS (desktop) • macos • darwin-arm64 • macOS 12.6 21G115 darwin-arm64 • Chrome (web) • chrome • web-javascript • Google Chrome 105.0.5195.125 [✓] HTTP Host Availability • All required HTTP hosts are available • No issues found! ```