Skip to content

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

@uiYzzi

Description

@uiYzzi

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:

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

TabView(
  tabs: tabs,
  onDragStart: (details) {
    // Custom drag handling (e.g., window dragging)
    windowManager.startDragging();
  },
)

Option 2: Add dragRegionBuilder callback

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.

Longshot20250727015227.mov

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions