bdlukaa / bdlukaa/fluent_ui

[Feature Request] Add drag region support to TabView header for window dragging

Open
#1,239 1 comment 0 reactions 0 assignees View on GitHub
enhancement w: TabView
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.