[Feature Request] Add drag region support to TabView header for window dragging
- Dominant language
- Dart
- Stars
- 3.5k
- Forks
- 506
- Avg merge
- 11d 2h
- Merged PRs (30d)
- 3
Description
## Problem Description
When building a frameless window application using `TabView` as the main UI component, there's currently no clean way to make the TabView header area draggable for window movement. This is a common requirement for modern desktop applications that want to provide window dragging functionality through the tab bar area.
Currently, to achieve window dragging through the TabView header, developers need to use invasive workarounds that involve:
1. Manipulating the TabView's internal widget structure through `stripBuilder`
2. Wrapping components with custom drag detection widgets
3. Complex logic to differentiate between tab dragging and window dragging
## Current Workaround (Invasive Implementation)
Here's the current approach I'm using, which demonstrates the complexity and invasiveness of the solution:
```dart
import 'package:fluent_ui/fluent_ui.dart';
import 'package:window_manager/window_manager.dart';
// Custom drag region widget
class CustomDragRegion extends StatelessWidget {
final Widget? child;
final HitTestBehavior behavior;
const CustomDragRegion({
super.key,
this.child,
this.behavior = HitTestBehavior.translucent,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onPanStart: (details) {
windowManager.startDragging();
},
behavior: behavior,
child: child ?? SizedBox.expand(child: Container(color: Colors.transparent)),
);
}
}
// Usage in TabView - requires complex stripBuilder manipulation
TabView(
tabs: tabs,
stripBuilder: (context, stripWidget) {
if (stripWidget is! Row) return stripWidget;
// Complex logic to wrap the strip with drag region
// while preserving tab functionality
return CustomDragRegion(child: stripWidget);
},
header: CustomDragRegion(
child: SizedBox(
width: 50.0,
child: Container(color: Colors.transparent),
),
),
)
```
## Proposed Solution
Add built-in support for window dragging in TabView through one of these approaches:
### Option 1: Add `onDragStart` callback to TabView
```dart
TabView(
tabs: tabs,
onDragStart: (details) {
// Custom drag handling (e.g., window dragging)
windowManager.startDragging();
},
)
```
### Option 2: Add `dragRegionBuilder` callback
```dart
TabView(
tabs: tabs,
dragRegionBuilder: (context, child) {
return GestureDetector(
onPanStart: (details) => windowManager.startDragging(),
child: child,
);
},
)
```
## Benefits
1. **Cleaner API**: Eliminates the need for complex `stripBuilder` manipulations
2. **Better maintainability**: Reduces coupling between window management and UI structure
3. **Improved developer experience**: Provides a standard way to implement this common pattern
4. **Performance**: Avoids unnecessary widget tree manipulations
## Use Cases
- Desktop applications with frameless windows
- Modern UI designs where the tab bar serves as the title bar
- Applications that need custom window dragging behavior
- Cross-platform desktop apps using Flutter
## Additional Context
This feature would be particularly valuable for desktop Flutter applications using packages like `window_manager` or `bitsdojo_window` for custom window management. The current workaround is functional but requires deep knowledge of TabView's internal structure and is fragile to future changes.
https://github.com/user-attachments/assets/31903144-a097-4028-bfc6-4c604f042de4
## Environment
- Flutter version: Channel stable, 3.32.1, on macOS 15.5 24F74 darwin-arm64, locale zh-Hans-CN
- fluent_ui version: 4.12.0
- Platform: Desktop (Windows/macOS/Linux)
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by locating the TabView implementation and its existing stripBuilder and header handling. Compare the proposed onDragStart and dragRegionBuilder APIs, then determine how tab interaction should coexist with window dragging on desktop. Done means a documented API, preserved tab behavior, and tests covering the new drag-region behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- dart, flutter
- Domain
- desktop, frontend
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100