Flutter Wayland显示层管理插件wayland_layer_shell的使用

发布于 1周前 作者 itying888 来自 Flutter

Flutter Wayland显示层管理插件wayland_layer_shell的使用

本插件通过使用gtk-layer-shell库来暴露zwlr_layer_shell_v1协议,使开发者能够在Wayland系统上使用Flutter创建桌面组件,如面板、任务栏、应用程序启动器等。

支持的合成器

该插件仅在Wayland系统上运行,并且只与支持zwlr_layer_shell_v1协议的Wayland合成器兼容。支持的合成器包括:

  • 基于wlroots的合成器(如Sway、Hyprland等)
  • 在Wayland上的KDE Plasma
  • 基于Mir的合成器(某些可能默认不启用该协议,需要使用--add-wayland-extension zwlr_layer_shell_v1

不支持的合成器包括:

  • Gnome-on-Wayland
  • 任何X11桌面

入门指南

使用gtk标题栏并在初始化图层表面之前显示gtk窗口会阻止图层表面的初始化,因此需要对Flutter的gtk窗口初始化代码进行一些更改。

更新文件linux/my_application.cc如下所示:

...

// Implements GApplication::activate.
static void my_application_activate(GApplication* application) {

  ...

- gboolean use_header_bar = TRUE;
+ gboolean use_header_bar = FALSE;

  ...
  
  gtk_window_set_default_size(window, 1280, 720);
- gtk_widget_show(GTK_WIDGET(window));
+ gtk_widget_realize(GTK_WIDGET(window));

  g_autoptr(FlDartProject) project = fl_dart_project_new();

...

依赖项

该插件依赖于gtk-layer-shell-0库。确保在安装使用此插件的应用程序的平台上可用。该库可以在主要发行版的存储库中找到:发行版包

使用方法

要了解如何使用,请查看example文件夹内的示例应用。

完整示例Demo

以下是一个完整的示例代码,展示了如何使用wayland_layer_shell插件。

import 'package:flutter/material.dart';
import 'package:wayland_layer_shell/types.dart';
import 'dart:async';

import 'package:wayland_layer_shell/wayland_layer_shell.dart';
import 'package:wayland_layer_shell_example/set_exclusive_zone.dart';
import 'package:wayland_layer_shell_example/set_keyboard.dart';
import 'package:wayland_layer_shell_example/set_monitor.dart';
import 'package:wayland_layer_shell_example/set_anchors.dart';
import 'package:wayland_layer_shell_example/set_layer.dart';
import 'package:wayland_layer_shell_example/set_margins.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final waylandLayerShellPlugin = WaylandLayerShell();
  bool isSupported = await waylandLayerShellPlugin.initialize(650, 600);
  if (!isSupported) {
    runApp(const MaterialApp(home: Center(child: Text('Not supported'))));
    return;
  }
  await waylandLayerShellPlugin
      .setKeyboardMode(ShellKeyboardMode.keyboardModeExclusive);
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Wayland Layer Shell example'),
        ),
        body: const Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  SetMonitor(),
                  SizedBox(width: 40),
                  SetExclusiveZone(),
                ],
              ),
              SizedBox(height: 20),
              SetLayer(),
              SizedBox(height: 10),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  SetKeyboard(),
                  SizedBox(
                    width: 120,
                    child: TextField(
                      autofocus: true,
                      decoration:
                          InputDecoration(labelText: 'Test Keyboard Mode'),
                    ),
                  )
                ],
              ),
              SizedBox(height: 20),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [SetAnchors(), SizedBox(width: 40), SetMargins()],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

更多关于Flutter Wayland显示层管理插件wayland_layer_shell的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Wayland显示层管理插件wayland_layer_shell的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用wayland_layer_shell插件进行Wayland显示层管理的示例代码。wayland_layer_shell插件允许Flutter应用与Wayland的Layer Shell协议进行交互,这对于需要在底层显示内容(如覆盖层或锁屏界面)的应用特别有用。

首先,你需要确保你的Flutter环境已经设置好,并且你的设备或模拟器支持Wayland。

1. 添加依赖

在你的pubspec.yaml文件中添加wayland_layer_shell依赖(注意:这是一个假设的包名,实际使用时请查找是否有可用的Wayland Layer Shell Flutter插件,或者你可能需要自己实现与Wayland的交互):

dependencies:
  flutter:
    sdk: flutter
  wayland_layer_shell: ^x.y.z  # 替换为实际版本号

2. 初始化插件并设置Layer Shell

在你的Flutter应用中,你需要初始化插件并配置Layer Shell。以下是一个简单的示例,展示了如何使用该插件:

import 'package:flutter/material.dart';
import 'package:wayland_layer_shell/wayland_layer_shell.dart'; // 假设的包路径

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Wayland Layer Shell Example'),
        ),
        body: LayerShellExample(),
      ),
    );
  }
}

class LayerShellExample extends StatefulWidget {
  @override
  _LayerShellExampleState createState() => _LayerShellExampleState();
}

class _LayerShellExampleState extends State<LayerShellExample> {
  WaylandLayerShell? _layerShell;

  @override
  void initState() {
    super.initState();
    // 初始化WaylandLayerShell
    _layerShell = WaylandLayerShell();

    // 配置Layer Shell(假设插件提供了这样的方法)
    _configureLayerShell();
  }

  void _configureLayerShell() {
    // 假设有一个配置Layer Shell的方法,例如setLayerType
    _layerShell?.setLayerType(LayerType.overlay); // 这是一个假设的枚举值

    // 设置Layer的内容(这里只是一个示例,实际内容可能复杂得多)
    _layerShell?.setContent(Container(
      color: Colors.black54.withOpacity(0.7),
      child: Center(
        child: Text(
          'This is an overlay layer',
          style: TextStyle(color: Colors.white),
        ),
      ),
    ));
  }

  @override
  Widget build(BuildContext context) {
    // 这里通常你的应用会构建常规的Flutter界面
    // Layer Shell的内容已经在_configureLayerShell中设置
    return Center(
      child: Text('Check the overlay layer'),
    );
  }

  @override
  void dispose() {
    // 清理资源
    _layerShell?.dispose();
    super.dispose();
  }
}

// 假设的WaylandLayerShell类及其方法(实际使用时需根据插件文档)
class WaylandLayerShell {
  // 假设的方法,实际插件可能有不同的API
  void setLayerType(LayerType type) {
    // 实现设置Layer类型的逻辑
  }

  void setContent(Widget content) {
    // 这里实际上Flutter的Widget不能直接用作Wayland的内容
    // 这只是一个概念上的示例。实际实现可能需要使用Native代码和平台通道
  }

  void dispose() {
    // 清理资源
  }
}

// 假设的LayerType枚举(实际使用时需根据插件文档)
enum LayerType {
  bottom,
  top,
  overlay,
  // 其他可能的类型
}

注意事项

  1. 实际插件API:上面的代码是基于假设的API,实际的Wayland Layer Shell Flutter插件可能有不同的API和配置方法。请参考插件的官方文档。

  2. 平台通道:由于Wayland是底层的显示协议,Flutter本身不直接支持。因此,你可能需要使用平台通道(Platform Channels)与原生代码进行交互,原生代码再与Wayland进行通信。

  3. 权限和配置:使用Layer Shell可能需要特定的权限和配置,确保你的应用有适当的权限,并且设备或模拟器支持Wayland。

  4. 测试和调试:在实际设备上测试你的应用,确保Layer Shell按预期工作。Wayland环境可能与X11或其他显示服务器有所不同。

由于wayland_layer_shell可能不是一个真实存在的Flutter插件(取决于当前的生态系统),你可能需要自己实现与Wayland的交互,或者查找是否有其他社区或第三方提供的解决方案。

回到顶部