semi working
This commit is contained in:
parent
c2e9137936
commit
440dc1a0f9
27 changed files with 500 additions and 301 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
rust_input: crate::api
|
rust_input: crate::api
|
||||||
rust_root: rust/
|
rust_root: rust/
|
||||||
dart_output: lib/src/rust
|
dart_output: lib/src/rust
|
||||||
|
enable_lifetime: true
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
import "package:flight/src/rust/api/model.dart";
|
|
||||||
import "package:flight/src/rust/api/workspace_api.dart";
|
import "package:flight/src/rust/api/workspace_api.dart";
|
||||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||||
|
|
||||||
class WorkspacesController extends StreamNotifier<List<Workspace>> {
|
class WorkspacesController extends StreamNotifier<List<Workspace>> {
|
||||||
@override
|
@override
|
||||||
Stream<List<Workspace>> build() => startWorkspaceStream();
|
Stream<List<Workspace>> build() => listenWorkspaces();
|
||||||
|
|
||||||
static final provider =
|
static final provider =
|
||||||
StreamNotifierProvider<WorkspacesController, List<Workspace>>(
|
StreamNotifierProvider<WorkspacesController, List<Workspace>>(
|
||||||
|
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
// This file is automatically generated, so please do not edit it.
|
|
||||||
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
|
||||||
|
|
||||||
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
|
||||||
|
|
||||||
import '../frb_generated.dart';
|
|
||||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
|
||||||
|
|
||||||
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `clone`, `fmt`
|
|
||||||
|
|
||||||
class Workspace {
|
|
||||||
final String? id;
|
|
||||||
final String name;
|
|
||||||
final bool active;
|
|
||||||
|
|
||||||
const Workspace({this.id, required this.name, required this.active});
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => id.hashCode ^ name.hashCode ^ active.hashCode;
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) =>
|
|
||||||
identical(this, other) ||
|
|
||||||
other is Workspace &&
|
|
||||||
runtimeType == other.runtimeType &&
|
|
||||||
id == other.id &&
|
|
||||||
name == other.name &&
|
|
||||||
active == other.active;
|
|
||||||
}
|
|
||||||
|
|
@ -4,8 +4,25 @@
|
||||||
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
||||||
|
|
||||||
import '../frb_generated.dart';
|
import '../frb_generated.dart';
|
||||||
import 'model.dart';
|
|
||||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||||
|
|
||||||
Stream<List<Workspace>> startWorkspaceStream() =>
|
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `clone`
|
||||||
RustLib.instance.api.crateApiWorkspaceApiStartWorkspaceStream();
|
|
||||||
|
Stream<List<Workspace>> listenWorkspaces() =>
|
||||||
|
RustLib.instance.api.crateApiWorkspaceApiListenWorkspaces();
|
||||||
|
|
||||||
|
class Workspace {
|
||||||
|
final bool activated;
|
||||||
|
|
||||||
|
const Workspace({required this.activated});
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => activated.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is Workspace &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
activated == other.activated;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
// This file is automatically generated, so please do not edit it.
|
||||||
|
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||||
|
|
||||||
|
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
||||||
|
|
||||||
|
import '../../frb_generated.dart';
|
||||||
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||||
|
|
||||||
|
// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `GroupCapabilities`
|
||||||
|
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `assert_receiver_is_total_eq`, `backend`, `bits`, `borrow`, `clone`, `clone`, `data`, `eq`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `fmt`, `from_bits_retain`, `from_id`, `from`, `hash`, `hash`, `id`, `inert`, `interface`, `object_data`, `parse_event`, `send_constructor`, `send_request`, `try_from`, `version`, `write_request`
|
||||||
|
|
||||||
|
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<ExtWorkspaceGroupHandleV1>>
|
||||||
|
abstract class ExtWorkspaceGroupHandleV1 implements RustOpaqueInterface {
|
||||||
|
///create a new workspace
|
||||||
|
///
|
||||||
|
///Request that the compositor create a new workspace with the given name
|
||||||
|
///and assign it to this group.
|
||||||
|
///
|
||||||
|
///There is no guarantee that the compositor will create a new workspace,
|
||||||
|
///or that the created workspace will have the provided name.
|
||||||
|
Future<void> createWorkspace({required String workspace});
|
||||||
|
|
||||||
|
///destroy the ext_workspace_group_handle_v1 object
|
||||||
|
///
|
||||||
|
///Destroys the ext_workspace_group_handle_v1 object.
|
||||||
|
///
|
||||||
|
///This request should be send either when the client does not want to
|
||||||
|
///use the workspace group object any more or after the removed event to finalize
|
||||||
|
///the destruction of the object.
|
||||||
|
Future<void> destroy();
|
||||||
|
}
|
||||||
54
lib/src/rust/api/workspace_api/ext_workspace_handle_v1.dart
Normal file
54
lib/src/rust/api/workspace_api/ext_workspace_handle_v1.dart
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
// This file is automatically generated, so please do not edit it.
|
||||||
|
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||||
|
|
||||||
|
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
||||||
|
|
||||||
|
import '../../frb_generated.dart';
|
||||||
|
import 'ext_workspace_group_handle_v1.dart';
|
||||||
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||||
|
|
||||||
|
// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `State`, `WorkspaceCapabilities`
|
||||||
|
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `backend`, `bits`, `bits`, `borrow`, `clone`, `clone`, `clone`, `data`, `eq`, `eq`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `from_bits_retain`, `from_bits_retain`, `from_id`, `from`, `from`, `hash`, `hash`, `hash`, `id`, `inert`, `interface`, `object_data`, `parse_event`, `send_constructor`, `send_request`, `try_from`, `try_from`, `version`, `write_request`
|
||||||
|
|
||||||
|
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<ExtWorkspaceHandleV1>>
|
||||||
|
abstract class ExtWorkspaceHandleV1 implements RustOpaqueInterface {
|
||||||
|
///activate the workspace
|
||||||
|
///
|
||||||
|
///Request that this workspace be activated.
|
||||||
|
///
|
||||||
|
///There is no guarantee the workspace will be actually activated, and
|
||||||
|
///behaviour may be compositor-dependent. For example, activating a
|
||||||
|
///workspace may or may not deactivate all other workspaces in the same
|
||||||
|
///group.
|
||||||
|
Future<void> activate();
|
||||||
|
|
||||||
|
///assign workspace to group
|
||||||
|
///
|
||||||
|
///Requests that this workspace is assigned to the given workspace group.
|
||||||
|
///
|
||||||
|
///There is no guarantee the workspace will be assigned.
|
||||||
|
Future<void> assign({required ExtWorkspaceGroupHandleV1 workspaceGroup});
|
||||||
|
|
||||||
|
///deactivate the workspace
|
||||||
|
///
|
||||||
|
///Request that this workspace be deactivated.
|
||||||
|
///
|
||||||
|
///There is no guarantee the workspace will be actually deactivated.
|
||||||
|
Future<void> deactivate();
|
||||||
|
|
||||||
|
///destroy the ext_workspace_handle_v1 object
|
||||||
|
///
|
||||||
|
///Destroys the ext_workspace_handle_v1 object.
|
||||||
|
///
|
||||||
|
///This request should be made either when the client does not want to
|
||||||
|
///use the workspace object any more or after the remove event to finalize
|
||||||
|
///the destruction of the object.
|
||||||
|
Future<void> destroy();
|
||||||
|
|
||||||
|
///remove the workspace
|
||||||
|
///
|
||||||
|
///Request that this workspace be removed.
|
||||||
|
///
|
||||||
|
///There is no guarantee the workspace will be actually removed.
|
||||||
|
Future<void> remove();
|
||||||
|
}
|
||||||
47
lib/src/rust/api/workspace_api/ext_workspace_manager_v1.dart
Normal file
47
lib/src/rust/api/workspace_api/ext_workspace_manager_v1.dart
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
// This file is automatically generated, so please do not edit it.
|
||||||
|
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||||
|
|
||||||
|
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
||||||
|
|
||||||
|
import '../../frb_generated.dart';
|
||||||
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||||
|
|
||||||
|
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `backend`, `borrow`, `clone`, `data`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `from_id`, `hash`, `id`, `inert`, `interface`, `object_data`, `parse_event`, `send_constructor`, `send_request`, `version`, `write_request`
|
||||||
|
|
||||||
|
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Event < >>>
|
||||||
|
abstract class Event implements RustOpaqueInterface {
|
||||||
|
///Get the opcode number of this message
|
||||||
|
Future<int> opcode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<ExtWorkspaceManagerV1>>
|
||||||
|
abstract class ExtWorkspaceManagerV1 implements RustOpaqueInterface {
|
||||||
|
///all requests about the workspaces have been sent
|
||||||
|
///
|
||||||
|
///The client must send this request after it has finished sending other
|
||||||
|
///requests. The compositor must process a series of requests preceding a
|
||||||
|
///commit request atomically.
|
||||||
|
///
|
||||||
|
///This allows changes to the workspace properties to be seen as atomic,
|
||||||
|
///even if they happen via multiple events, and even if they involve
|
||||||
|
///multiple ext_workspace_handle_v1 objects, for example, deactivating one
|
||||||
|
///workspace and activating another.
|
||||||
|
Future<void> commit();
|
||||||
|
|
||||||
|
///stop sending events
|
||||||
|
///
|
||||||
|
///Indicates the client no longer wishes to receive events for new
|
||||||
|
///workspace groups. However the compositor may emit further workspace
|
||||||
|
///events, until the finished event is emitted. The compositor is expected
|
||||||
|
///to send the finished event eventually once the stop request has been processed.
|
||||||
|
///
|
||||||
|
///The client must not send any requests after this one, doing so will raise a wl_display
|
||||||
|
///invalid_object error.
|
||||||
|
Future<void> stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Lifetimeable < Request < 'static > >>>
|
||||||
|
abstract class Request implements RustOpaqueInterface {
|
||||||
|
///Get the opcode number of this message
|
||||||
|
Future<int> opcode();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
// This file is automatically generated, so please do not edit it.
|
||||||
|
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||||
|
|
||||||
|
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
||||||
|
|
||||||
|
import '../../../frb_generated.dart';
|
||||||
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||||
|
|
||||||
|
// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `GroupCapabilities`
|
||||||
|
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `assert_receiver_is_total_eq`, `backend`, `bits`, `borrow`, `clone`, `clone`, `data`, `eq`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `fmt`, `from_bits_retain`, `from_id`, `from`, `hash`, `hash`, `id`, `inert`, `interface`, `object_data`, `parse_event`, `send_constructor`, `send_request`, `try_from`, `version`, `write_request`
|
||||||
|
|
||||||
|
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<ExtWorkspaceGroupHandleV1>>
|
||||||
|
abstract class ExtWorkspaceGroupHandleV1 implements RustOpaqueInterface {
|
||||||
|
///create a new workspace
|
||||||
|
///
|
||||||
|
///Request that the compositor create a new workspace with the given name
|
||||||
|
///and assign it to this group.
|
||||||
|
///
|
||||||
|
///There is no guarantee that the compositor will create a new workspace,
|
||||||
|
///or that the created workspace will have the provided name.
|
||||||
|
Future<void> createWorkspace({required String workspace});
|
||||||
|
|
||||||
|
///destroy the ext_workspace_group_handle_v1 object
|
||||||
|
///
|
||||||
|
///Destroys the ext_workspace_group_handle_v1 object.
|
||||||
|
///
|
||||||
|
///This request should be send either when the client does not want to
|
||||||
|
///use the workspace group object any more or after the removed event to finalize
|
||||||
|
///the destruction of the object.
|
||||||
|
Future<void> destroy();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
// This file is automatically generated, so please do not edit it.
|
||||||
|
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||||
|
|
||||||
|
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
||||||
|
|
||||||
|
import '../../../frb_generated.dart';
|
||||||
|
import 'ext_workspace_group_handle_v1.dart';
|
||||||
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||||
|
|
||||||
|
// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `State`, `WorkspaceCapabilities`
|
||||||
|
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `backend`, `bits`, `bits`, `borrow`, `clone`, `clone`, `clone`, `data`, `eq`, `eq`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `from_bits_retain`, `from_bits_retain`, `from_id`, `from`, `from`, `hash`, `hash`, `hash`, `id`, `inert`, `interface`, `object_data`, `parse_event`, `send_constructor`, `send_request`, `try_from`, `try_from`, `version`, `write_request`
|
||||||
|
|
||||||
|
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<ExtWorkspaceHandleV1>>
|
||||||
|
abstract class ExtWorkspaceHandleV1 implements RustOpaqueInterface {
|
||||||
|
///activate the workspace
|
||||||
|
///
|
||||||
|
///Request that this workspace be activated.
|
||||||
|
///
|
||||||
|
///There is no guarantee the workspace will be actually activated, and
|
||||||
|
///behaviour may be compositor-dependent. For example, activating a
|
||||||
|
///workspace may or may not deactivate all other workspaces in the same
|
||||||
|
///group.
|
||||||
|
Future<void> activate();
|
||||||
|
|
||||||
|
///assign workspace to group
|
||||||
|
///
|
||||||
|
///Requests that this workspace is assigned to the given workspace group.
|
||||||
|
///
|
||||||
|
///There is no guarantee the workspace will be assigned.
|
||||||
|
Future<void> assign({required ExtWorkspaceGroupHandleV1 workspaceGroup});
|
||||||
|
|
||||||
|
///deactivate the workspace
|
||||||
|
///
|
||||||
|
///Request that this workspace be deactivated.
|
||||||
|
///
|
||||||
|
///There is no guarantee the workspace will be actually deactivated.
|
||||||
|
Future<void> deactivate();
|
||||||
|
|
||||||
|
///destroy the ext_workspace_handle_v1 object
|
||||||
|
///
|
||||||
|
///Destroys the ext_workspace_handle_v1 object.
|
||||||
|
///
|
||||||
|
///This request should be made either when the client does not want to
|
||||||
|
///use the workspace object any more or after the remove event to finalize
|
||||||
|
///the destruction of the object.
|
||||||
|
Future<void> destroy();
|
||||||
|
|
||||||
|
///remove the workspace
|
||||||
|
///
|
||||||
|
///Request that this workspace be removed.
|
||||||
|
///
|
||||||
|
///There is no guarantee the workspace will be actually removed.
|
||||||
|
Future<void> remove();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
// This file is automatically generated, so please do not edit it.
|
||||||
|
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||||
|
|
||||||
|
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
||||||
|
|
||||||
|
import '../../../frb_generated.dart';
|
||||||
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||||
|
|
||||||
|
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `backend`, `borrow`, `clone`, `data`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `from_id`, `hash`, `id`, `inert`, `interface`, `object_data`, `parse_event`, `send_constructor`, `send_request`, `version`, `write_request`
|
||||||
|
|
||||||
|
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Event < >>>
|
||||||
|
abstract class Event implements RustOpaqueInterface {
|
||||||
|
///Get the opcode number of this message
|
||||||
|
Future<int> opcode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<ExtWorkspaceManagerV1>>
|
||||||
|
abstract class ExtWorkspaceManagerV1 implements RustOpaqueInterface {
|
||||||
|
///all requests about the workspaces have been sent
|
||||||
|
///
|
||||||
|
///The client must send this request after it has finished sending other
|
||||||
|
///requests. The compositor must process a series of requests preceding a
|
||||||
|
///commit request atomically.
|
||||||
|
///
|
||||||
|
///This allows changes to the workspace properties to be seen as atomic,
|
||||||
|
///even if they happen via multiple events, and even if they involve
|
||||||
|
///multiple ext_workspace_handle_v1 objects, for example, deactivating one
|
||||||
|
///workspace and activating another.
|
||||||
|
Future<void> commit();
|
||||||
|
|
||||||
|
///stop sending events
|
||||||
|
///
|
||||||
|
///Indicates the client no longer wishes to receive events for new
|
||||||
|
///workspace groups. However the compositor may emit further workspace
|
||||||
|
///events, until the finished event is emitted. The compositor is expected
|
||||||
|
///to send the finished event eventually once the stop request has been processed.
|
||||||
|
///
|
||||||
|
///The client must not send any requests after this one, doing so will raise a wl_display
|
||||||
|
///invalid_object error.
|
||||||
|
Future<void> stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Lifetimeable < Request < 'static > >>>
|
||||||
|
abstract class Request implements RustOpaqueInterface {
|
||||||
|
///Get the opcode number of this message
|
||||||
|
Future<int> opcode();
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
||||||
|
|
||||||
import 'api/model.dart';
|
|
||||||
import 'api/workspace_api.dart';
|
import 'api/workspace_api.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
@ -65,7 +64,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
||||||
String get codegenVersion => '2.11.1';
|
String get codegenVersion => '2.11.1';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get rustContentHash => 804335101;
|
int get rustContentHash => 1397669831;
|
||||||
|
|
||||||
static const kDefaultExternalLibraryLoaderConfig =
|
static const kDefaultExternalLibraryLoaderConfig =
|
||||||
ExternalLibraryLoaderConfig(
|
ExternalLibraryLoaderConfig(
|
||||||
|
|
@ -76,7 +75,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class RustLibApi extends BaseApi {
|
abstract class RustLibApi extends BaseApi {
|
||||||
Stream<List<Workspace>> crateApiWorkspaceApiStartWorkspaceStream();
|
Stream<List<Workspace>> crateApiWorkspaceApiListenWorkspaces();
|
||||||
}
|
}
|
||||||
|
|
||||||
class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||||
|
|
@ -88,7 +87,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<List<Workspace>> crateApiWorkspaceApiStartWorkspaceStream() {
|
Stream<List<Workspace>> crateApiWorkspaceApiListenWorkspaces() {
|
||||||
final sink = RustStreamSink<List<Workspace>>();
|
final sink = RustStreamSink<List<Workspace>>();
|
||||||
unawaited(
|
unawaited(
|
||||||
handler.executeNormal(
|
handler.executeNormal(
|
||||||
|
|
@ -105,9 +104,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_unit,
|
decodeSuccessData: sse_decode_unit,
|
||||||
decodeErrorData: null,
|
decodeErrorData: sse_decode_AnyhowException,
|
||||||
),
|
),
|
||||||
constMeta: kCrateApiWorkspaceApiStartWorkspaceStreamConstMeta,
|
constMeta: kCrateApiWorkspaceApiListenWorkspacesConstMeta,
|
||||||
argValues: [sink],
|
argValues: [sink],
|
||||||
apiImpl: this,
|
apiImpl: this,
|
||||||
),
|
),
|
||||||
|
|
@ -116,11 +115,8 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||||
return sink.stream;
|
return sink.stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskConstMeta get kCrateApiWorkspaceApiStartWorkspaceStreamConstMeta =>
|
TaskConstMeta get kCrateApiWorkspaceApiListenWorkspacesConstMeta =>
|
||||||
const TaskConstMeta(
|
const TaskConstMeta(debugName: "listen_workspaces", argNames: ["sink"]);
|
||||||
debugName: "start_workspace_stream",
|
|
||||||
argNames: ["sink"],
|
|
||||||
);
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
AnyhowException dco_decode_AnyhowException(dynamic raw) {
|
AnyhowException dco_decode_AnyhowException(dynamic raw) {
|
||||||
|
|
@ -160,12 +156,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||||
return (raw as List<dynamic>).map(dco_decode_workspace).toList();
|
return (raw as List<dynamic>).map(dco_decode_workspace).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
|
||||||
String? dco_decode_opt_String(dynamic raw) {
|
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
|
||||||
return raw == null ? null : dco_decode_String(raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
int dco_decode_u_8(dynamic raw) {
|
int dco_decode_u_8(dynamic raw) {
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
|
|
@ -182,13 +172,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||||
Workspace dco_decode_workspace(dynamic raw) {
|
Workspace dco_decode_workspace(dynamic raw) {
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
final arr = raw as List<dynamic>;
|
final arr = raw as List<dynamic>;
|
||||||
if (arr.length != 3)
|
if (arr.length != 1)
|
||||||
throw Exception('unexpected arr length: expect 3 but see ${arr.length}');
|
throw Exception('unexpected arr length: expect 1 but see ${arr.length}');
|
||||||
return Workspace(
|
return Workspace(activated: dco_decode_bool(arr[0]));
|
||||||
id: dco_decode_opt_String(arr[0]),
|
|
||||||
name: dco_decode_String(arr[1]),
|
|
||||||
active: dco_decode_bool(arr[2]),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
|
|
@ -238,17 +224,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||||
return ans_;
|
return ans_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
|
||||||
String? sse_decode_opt_String(SseDeserializer deserializer) {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
|
|
||||||
if (sse_decode_bool(deserializer)) {
|
|
||||||
return (sse_decode_String(deserializer));
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
int sse_decode_u_8(SseDeserializer deserializer) {
|
int sse_decode_u_8(SseDeserializer deserializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
|
@ -263,10 +238,8 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||||
@protected
|
@protected
|
||||||
Workspace sse_decode_workspace(SseDeserializer deserializer) {
|
Workspace sse_decode_workspace(SseDeserializer deserializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
var var_id = sse_decode_opt_String(deserializer);
|
var var_activated = sse_decode_bool(deserializer);
|
||||||
var var_name = sse_decode_String(deserializer);
|
return Workspace(activated: var_activated);
|
||||||
var var_active = sse_decode_bool(deserializer);
|
|
||||||
return Workspace(id: var_id, name: var_name, active: var_active);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
|
|
@ -335,16 +308,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
|
||||||
void sse_encode_opt_String(String? self, SseSerializer serializer) {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
|
|
||||||
sse_encode_bool(self != null, serializer);
|
|
||||||
if (self != null) {
|
|
||||||
sse_encode_String(self, serializer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_u_8(int self, SseSerializer serializer) {
|
void sse_encode_u_8(int self, SseSerializer serializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
|
@ -359,9 +322,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_workspace(Workspace self, SseSerializer serializer) {
|
void sse_encode_workspace(Workspace self, SseSerializer serializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
sse_encode_opt_String(self.id, serializer);
|
sse_encode_bool(self.activated, serializer);
|
||||||
sse_encode_String(self.name, serializer);
|
|
||||||
sse_encode_bool(self.active, serializer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
||||||
|
|
||||||
import 'api/model.dart';
|
|
||||||
import 'api/workspace_api.dart';
|
import 'api/workspace_api.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
@ -39,9 +38,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||||
@protected
|
@protected
|
||||||
List<Workspace> dco_decode_list_workspace(dynamic raw);
|
List<Workspace> dco_decode_list_workspace(dynamic raw);
|
||||||
|
|
||||||
@protected
|
|
||||||
String? dco_decode_opt_String(dynamic raw);
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
int dco_decode_u_8(dynamic raw);
|
int dco_decode_u_8(dynamic raw);
|
||||||
|
|
||||||
|
|
@ -71,9 +67,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||||
@protected
|
@protected
|
||||||
List<Workspace> sse_decode_list_workspace(SseDeserializer deserializer);
|
List<Workspace> sse_decode_list_workspace(SseDeserializer deserializer);
|
||||||
|
|
||||||
@protected
|
|
||||||
String? sse_decode_opt_String(SseDeserializer deserializer);
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
int sse_decode_u_8(SseDeserializer deserializer);
|
int sse_decode_u_8(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
|
@ -116,9 +109,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||||
SseSerializer serializer,
|
SseSerializer serializer,
|
||||||
);
|
);
|
||||||
|
|
||||||
@protected
|
|
||||||
void sse_encode_opt_String(String? self, SseSerializer serializer);
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_u_8(int self, SseSerializer serializer);
|
void sse_encode_u_8(int self, SseSerializer serializer);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
// Static analysis wrongly picks the IO variant, thus ignore this
|
// Static analysis wrongly picks the IO variant, thus ignore this
|
||||||
// ignore_for_file: argument_type_not_assignable
|
// ignore_for_file: argument_type_not_assignable
|
||||||
|
|
||||||
import 'api/model.dart';
|
|
||||||
import 'api/workspace_api.dart';
|
import 'api/workspace_api.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
@ -41,9 +40,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||||
@protected
|
@protected
|
||||||
List<Workspace> dco_decode_list_workspace(dynamic raw);
|
List<Workspace> dco_decode_list_workspace(dynamic raw);
|
||||||
|
|
||||||
@protected
|
|
||||||
String? dco_decode_opt_String(dynamic raw);
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
int dco_decode_u_8(dynamic raw);
|
int dco_decode_u_8(dynamic raw);
|
||||||
|
|
||||||
|
|
@ -73,9 +69,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||||
@protected
|
@protected
|
||||||
List<Workspace> sse_decode_list_workspace(SseDeserializer deserializer);
|
List<Workspace> sse_decode_list_workspace(SseDeserializer deserializer);
|
||||||
|
|
||||||
@protected
|
|
||||||
String? sse_decode_opt_String(SseDeserializer deserializer);
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
int sse_decode_u_8(SseDeserializer deserializer);
|
int sse_decode_u_8(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
|
@ -118,9 +111,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||||
SseSerializer serializer,
|
SseSerializer serializer,
|
||||||
);
|
);
|
||||||
|
|
||||||
@protected
|
|
||||||
void sse_encode_opt_String(String? self, SseSerializer serializer);
|
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_u_8(int self, SseSerializer serializer);
|
void sse_encode_u_8(int self, SseSerializer serializer);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:flight/controllers/time_controller.dart';
|
import 'package:flight/controllers/time_controller.dart';
|
||||||
import 'package:flight/controllers/workspaces_controller.dart';
|
import 'package:flight/controllers/workspaces_controller.dart';
|
||||||
|
import 'package:flight/widgets/loading.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
@ -24,18 +27,24 @@ class Bar extends ConsumerWidget {
|
||||||
ref
|
ref
|
||||||
.watch(WorkspacesController.provider)
|
.watch(WorkspacesController.provider)
|
||||||
.whenOrNull(
|
.whenOrNull(
|
||||||
data: (value) => value
|
error: (error, stackTrace) => [
|
||||||
.map(
|
Text(error.toString()),
|
||||||
(element) => IconButton(
|
],
|
||||||
onPressed: () {},
|
loading: () => [Text("loading")],
|
||||||
icon: Icon(
|
data: (value) {
|
||||||
element.active
|
return value
|
||||||
? Icons.circle
|
.map(
|
||||||
: Icons.circle_outlined,
|
(element) => IconButton(
|
||||||
|
onPressed: () {},
|
||||||
|
icon: Icon(
|
||||||
|
element.activated
|
||||||
|
? Icons.circle
|
||||||
|
: Icons.circle_outlined,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
)
|
.toList();
|
||||||
.toList(),
|
},
|
||||||
) ??
|
) ??
|
||||||
[],
|
[],
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ pkgs.mkShell {
|
||||||
gtk-layer-shell
|
gtk-layer-shell
|
||||||
|
|
||||||
cargo
|
cargo
|
||||||
|
rustfmt
|
||||||
flutter_rust_bridge_codegen
|
flutter_rust_bridge_codegen
|
||||||
(pkgs.writeShellScriptBin "rustup" (builtins.readFile ./fake-rustup.sh))
|
(pkgs.writeShellScriptBin "rustup" (builtins.readFile ./fake-rustup.sh))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,11 @@ edition = "2021"
|
||||||
crate-type = ["cdylib", "staticlib"]
|
crate-type = ["cdylib", "staticlib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
wayland-scanner = "0.31"
|
||||||
flutter_rust_bridge = "=2.11.1"
|
flutter_rust_bridge = "=2.11.1"
|
||||||
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
|
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
|
|
||||||
wayland-client = "0.31"
|
wayland-client = "0.31"
|
||||||
wayland-scanner = "0.31"
|
|
||||||
|
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1 @@
|
||||||
pub mod model;
|
|
||||||
pub mod workspace_api;
|
pub mod workspace_api;
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
use serde::{Serialize, Deserialize};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
pub struct Workspace {
|
|
||||||
pub id: Option<String>,
|
|
||||||
pub name: String,
|
|
||||||
pub active: bool,
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +1,38 @@
|
||||||
use crate::frb_generated::StreamSink;
|
use serde_json::Result;
|
||||||
use crate::api::model::Workspace;
|
use wayland_client::{Connection, EventQueue};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use crate::{frb_generated::StreamSink, internal::wayland::AppState};
|
||||||
|
|
||||||
pub fn start_workspace_stream(sink: StreamSink<Vec<Workspace>>) {
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Workspace {
|
||||||
|
pub activated: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn listen_workspaces(sink: StreamSink<Vec<Workspace>>) -> Result<()> {
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
|
// Connect to Wayland
|
||||||
|
let conn = Connection::connect_to_env().expect("Failed to connect to Wayland");
|
||||||
|
|
||||||
|
let mut event_queue: EventQueue<AppState> = conn.new_event_queue();
|
||||||
|
let qh = event_queue.handle();
|
||||||
|
|
||||||
|
// Initialize state
|
||||||
|
let mut state = AppState {
|
||||||
|
workspaces: HashMap::new(),
|
||||||
|
sink,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get registry (this triggers wl_registry events → binds manager)
|
||||||
|
conn.display().get_registry(&qh, ());
|
||||||
|
|
||||||
|
// Main event loop
|
||||||
loop {
|
loop {
|
||||||
// Replace with real shared state later
|
event_queue
|
||||||
let data = vec![];
|
.blocking_dispatch(&mut state)
|
||||||
|
.expect("Wayland dispatch failed");
|
||||||
sink.add(data).ok();
|
|
||||||
|
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -37,7 +37,7 @@ flutter_rust_bridge::frb_generated_boilerplate!(
|
||||||
default_rust_auto_opaque = RustAutoOpaqueMoi,
|
default_rust_auto_opaque = RustAutoOpaqueMoi,
|
||||||
);
|
);
|
||||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.11.1";
|
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.11.1";
|
||||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 804335101;
|
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 1397669831;
|
||||||
|
|
||||||
|
|
||||||
// Section: executor
|
// Section: executor
|
||||||
|
|
@ -46,13 +46,13 @@ flutter_rust_bridge::frb_generated_default_handler!();
|
||||||
|
|
||||||
// Section: wire_funcs
|
// Section: wire_funcs
|
||||||
|
|
||||||
fn wire__crate__api__workspace_api__start_workspace_stream_impl(port_: flutter_rust_bridge::for_generated::MessagePort,ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,rust_vec_len_: i32,data_len_: i32) {
|
fn wire__crate__api__workspace_api__listen_workspaces_impl(port_: flutter_rust_bridge::for_generated::MessagePort,ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,rust_vec_len_: i32,data_len_: i32) {
|
||||||
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "start_workspace_stream", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || {
|
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "listen_workspaces", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || {
|
||||||
let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) };
|
let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) };
|
||||||
let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message);
|
let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message);
|
||||||
let api_sink = <StreamSink<Vec<crate::api::model::Workspace>,flutter_rust_bridge::for_generated::SseCodec>>::sse_decode(&mut deserializer);deserializer.end(); move |context| {
|
let api_sink = <StreamSink<Vec<crate::api::workspace_api::Workspace>,flutter_rust_bridge::for_generated::SseCodec>>::sse_decode(&mut deserializer);deserializer.end(); move |context| {
|
||||||
transform_result_sse::<_, ()>((move || {
|
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>((move || {
|
||||||
let output_ok = Result::<_,()>::Ok({ crate::api::workspace_api::start_workspace_stream(api_sink); })?; Ok(output_ok)
|
let output_ok = crate::api::workspace_api::listen_workspaces(api_sink)?; Ok(output_ok)
|
||||||
})())
|
})())
|
||||||
} })
|
} })
|
||||||
}
|
}
|
||||||
|
|
@ -66,7 +66,7 @@ fn wire__crate__api__workspace_api__start_workspace_stream_impl(port_: flutter_r
|
||||||
return flutter_rust_bridge::for_generated::anyhow::anyhow!("{}", inner);}
|
return flutter_rust_bridge::for_generated::anyhow::anyhow!("{}", inner);}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SseDecode for StreamSink<Vec<crate::api::model::Workspace>,flutter_rust_bridge::for_generated::SseCodec> {
|
impl SseDecode for StreamSink<Vec<crate::api::workspace_api::Workspace>,flutter_rust_bridge::for_generated::SseCodec> {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {let mut inner = <String>::sse_decode(deserializer);
|
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {let mut inner = <String>::sse_decode(deserializer);
|
||||||
return StreamSink::deserialize(inner);}
|
return StreamSink::deserialize(inner);}
|
||||||
|
|
@ -91,23 +91,14 @@ fn wire__crate__api__workspace_api__start_workspace_stream_impl(port_: flutter_r
|
||||||
return ans_;}
|
return ans_;}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SseDecode for Vec<crate::api::model::Workspace> {
|
impl SseDecode for Vec<crate::api::workspace_api::Workspace> {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {let mut len_ = <i32>::sse_decode(deserializer);
|
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {let mut len_ = <i32>::sse_decode(deserializer);
|
||||||
let mut ans_ = vec![];
|
let mut ans_ = vec![];
|
||||||
for idx_ in 0..len_ { ans_.push(<crate::api::model::Workspace>::sse_decode(deserializer)); }
|
for idx_ in 0..len_ { ans_.push(<crate::api::workspace_api::Workspace>::sse_decode(deserializer)); }
|
||||||
return ans_;}
|
return ans_;}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SseDecode for Option<String> {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {if (<bool>::sse_decode(deserializer)) {
|
|
||||||
return Some(<String>::sse_decode(deserializer));
|
|
||||||
} else {
|
|
||||||
return None;
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SseDecode for u8 {
|
impl SseDecode for u8 {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {deserializer.cursor.read_u8().unwrap()}
|
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {deserializer.cursor.read_u8().unwrap()}
|
||||||
|
|
@ -118,12 +109,10 @@ fn wire__crate__api__workspace_api__start_workspace_stream_impl(port_: flutter_r
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {}
|
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SseDecode for crate::api::model::Workspace {
|
impl SseDecode for crate::api::workspace_api::Workspace {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {let mut var_id = <Option<String>>::sse_decode(deserializer);
|
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {let mut var_activated = <bool>::sse_decode(deserializer);
|
||||||
let mut var_name = <String>::sse_decode(deserializer);
|
return crate::api::workspace_api::Workspace{activated: var_activated};}
|
||||||
let mut var_active = <bool>::sse_decode(deserializer);
|
|
||||||
return crate::api::model::Workspace{id: var_id, name: var_name, active: var_active};}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SseDecode for i32 {
|
impl SseDecode for i32 {
|
||||||
|
|
@ -139,7 +128,7 @@ return crate::api::model::Workspace{id: var_id, name: var_name, active: var_acti
|
||||||
) {
|
) {
|
||||||
// Codec=Pde (Serialization + dispatch), see doc to use other codecs
|
// Codec=Pde (Serialization + dispatch), see doc to use other codecs
|
||||||
match func_id {
|
match func_id {
|
||||||
1 => wire__crate__api__workspace_api__start_workspace_stream_impl(port, ptr, rust_vec_len, data_len),
|
1 => wire__crate__api__workspace_api__listen_workspaces_impl(port, ptr, rust_vec_len, data_len),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -161,18 +150,16 @@ return crate::api::model::Workspace{id: var_id, name: var_name, active: var_acti
|
||||||
// Section: rust2dart
|
// Section: rust2dart
|
||||||
|
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
impl flutter_rust_bridge::IntoDart for crate::api::model::Workspace {
|
impl flutter_rust_bridge::IntoDart for crate::api::workspace_api::Workspace {
|
||||||
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
|
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
|
||||||
[
|
[
|
||||||
self.id.into_into_dart().into_dart(),
|
self.activated.into_into_dart().into_dart()
|
||||||
self.name.into_into_dart().into_dart(),
|
|
||||||
self.active.into_into_dart().into_dart()
|
|
||||||
].into_dart()
|
].into_dart()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::api::model::Workspace {}
|
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::api::workspace_api::Workspace {}
|
||||||
impl flutter_rust_bridge::IntoIntoDart<crate::api::model::Workspace> for crate::api::model::Workspace {
|
impl flutter_rust_bridge::IntoIntoDart<crate::api::workspace_api::Workspace> for crate::api::workspace_api::Workspace {
|
||||||
fn into_into_dart(self) -> crate::api::model::Workspace {
|
fn into_into_dart(self) -> crate::api::workspace_api::Workspace {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -182,7 +169,7 @@ impl flutter_rust_bridge::IntoIntoDart<crate::api::model::Workspace> for crate::
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {<String>::sse_encode(format!("{:?}", self), serializer);}
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {<String>::sse_encode(format!("{:?}", self), serializer);}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SseEncode for StreamSink<Vec<crate::api::model::Workspace>,flutter_rust_bridge::for_generated::SseCodec> {
|
impl SseEncode for StreamSink<Vec<crate::api::workspace_api::Workspace>,flutter_rust_bridge::for_generated::SseCodec> {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {unimplemented!("")}
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {unimplemented!("")}
|
||||||
}
|
}
|
||||||
|
|
@ -203,18 +190,10 @@ impl flutter_rust_bridge::IntoIntoDart<crate::api::model::Workspace> for crate::
|
||||||
for item in self { <u8>::sse_encode(item, serializer); }}
|
for item in self { <u8>::sse_encode(item, serializer); }}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SseEncode for Vec<crate::api::model::Workspace> {
|
impl SseEncode for Vec<crate::api::workspace_api::Workspace> {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {<i32>::sse_encode(self.len() as _, serializer);
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {<i32>::sse_encode(self.len() as _, serializer);
|
||||||
for item in self { <crate::api::model::Workspace>::sse_encode(item, serializer); }}
|
for item in self { <crate::api::workspace_api::Workspace>::sse_encode(item, serializer); }}
|
||||||
}
|
|
||||||
|
|
||||||
impl SseEncode for Option<String> {
|
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {<bool>::sse_encode(self.is_some(), serializer);
|
|
||||||
if let Some(value) = self {
|
|
||||||
<String>::sse_encode(value, serializer);
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SseEncode for u8 {
|
impl SseEncode for u8 {
|
||||||
|
|
@ -227,11 +206,9 @@ impl flutter_rust_bridge::IntoIntoDart<crate::api::model::Workspace> for crate::
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {}
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SseEncode for crate::api::model::Workspace {
|
impl SseEncode for crate::api::workspace_api::Workspace {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {<Option<String>>::sse_encode(self.id, serializer);
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {<bool>::sse_encode(self.activated, serializer);}
|
||||||
<String>::sse_encode(self.name, serializer);
|
|
||||||
<bool>::sse_encode(self.active, serializer);}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SseEncode for i32 {
|
impl SseEncode for i32 {
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1 @@
|
||||||
pub mod state;
|
|
||||||
pub mod wayland;
|
pub mod wayland;
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
use std::collections::HashMap;
|
|
||||||
use crate::api::model::Workspace;
|
|
||||||
|
|
||||||
pub struct AppState {
|
|
||||||
pub workspaces: HashMap<String, Workspace>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AppState {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
workspaces: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
122
rust/src/internal/wayland.rs
Normal file
122
rust/src/internal/wayland.rs
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
use crate::{frb_generated::StreamSink, workspace_api::Workspace};
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use wayland_client::{self, Connection, Dispatch, QueueHandle, event_created_child, protocol::{__interfaces::{WL_OUTPUT_INTERFACE, wl_output_interface}, wl_output, wl_registry}};
|
||||||
|
|
||||||
|
|
||||||
|
wayland_scanner::generate_interfaces!("protocols/ext-workspace-v1.xml");
|
||||||
|
wayland_scanner::generate_client_code!("protocols/ext-workspace-v1.xml");
|
||||||
|
|
||||||
|
|
||||||
|
pub struct AppState {
|
||||||
|
pub workspaces: HashMap<u32, Workspace>,
|
||||||
|
pub sink: StreamSink<Vec<Workspace>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppState {
|
||||||
|
fn emit(&self) {
|
||||||
|
let _ = self.sink.add(self.workspaces.values().cloned().collect());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------
|
||||||
|
// wl_registry
|
||||||
|
// ------------------------
|
||||||
|
impl Dispatch<wl_registry::WlRegistry, ()> for AppState {
|
||||||
|
fn event(
|
||||||
|
_state: &mut Self,
|
||||||
|
registry: &wl_registry::WlRegistry,
|
||||||
|
event: wl_registry::Event,
|
||||||
|
_data: &(),
|
||||||
|
_conn: &Connection,
|
||||||
|
qh: &QueueHandle<Self>,
|
||||||
|
) {
|
||||||
|
if let wl_registry::Event::Global {
|
||||||
|
name,
|
||||||
|
interface,
|
||||||
|
version,
|
||||||
|
} = event
|
||||||
|
{
|
||||||
|
if interface == "ext_workspace_manager_v1" {
|
||||||
|
registry.bind::<ext_workspace_manager_v1::ExtWorkspaceManagerV1, _, _>(
|
||||||
|
name,
|
||||||
|
version.min(1),
|
||||||
|
qh,
|
||||||
|
(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
impl Dispatch<ext_workspace_manager_v1::ExtWorkspaceManagerV1, ()> for AppState {
|
||||||
|
fn event(
|
||||||
|
_state: &mut Self,
|
||||||
|
_proxy: &ext_workspace_manager_v1::ExtWorkspaceManagerV1,
|
||||||
|
_event: ext_workspace_manager_v1::Event,
|
||||||
|
_data: &(),
|
||||||
|
_conn: &Connection,
|
||||||
|
_qh: &QueueHandle<Self>,
|
||||||
|
) {
|
||||||
|
// unused for now
|
||||||
|
}
|
||||||
|
|
||||||
|
event_created_child!(
|
||||||
|
AppState,
|
||||||
|
ext_workspace_manager_v1::ExtWorkspaceManagerV1,
|
||||||
|
[
|
||||||
|
_workspace => (
|
||||||
|
ext_workspace_handle_v1::ExtWorkspaceHandleV1,
|
||||||
|
()
|
||||||
|
)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------
|
||||||
|
// workspace handle
|
||||||
|
// ------------------------
|
||||||
|
impl Dispatch<ext_workspace_handle_v1::ExtWorkspaceHandleV1, ()> for AppState {
|
||||||
|
fn event(
|
||||||
|
state: &mut Self,
|
||||||
|
_proxy: &ext_workspace_handle_v1::ExtWorkspaceHandleV1,
|
||||||
|
event: ext_workspace_handle_v1::Event,
|
||||||
|
_data: &(),
|
||||||
|
_conn: &Connection,
|
||||||
|
_qh: &QueueHandle<Self>,
|
||||||
|
) {
|
||||||
|
match event {
|
||||||
|
ext_workspace_handle_v1::Event::Id { id } => {
|
||||||
|
let id: u32 = id.parse().unwrap_or(0);
|
||||||
|
|
||||||
|
state.workspaces.insert(id, Workspace { activated: false });
|
||||||
|
|
||||||
|
state.emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
ext_workspace_handle_v1::Event::State { state: flags } => {
|
||||||
|
let active = matches!(
|
||||||
|
flags,
|
||||||
|
wayland_client::WEnum::Value(ext_workspace_handle_v1::State::Active)
|
||||||
|
);
|
||||||
|
|
||||||
|
for ws in state.workspaces.values_mut() {
|
||||||
|
ws.activated = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ext_workspace_handle_v1::Event::Removed => {
|
||||||
|
// let id: u32 = id.parse().unwrap_or(0);
|
||||||
|
|
||||||
|
// state.workspaces.remove(&id);
|
||||||
|
// state.emit();
|
||||||
|
// }
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
use wayland_client::{Connection, EventQueue};
|
|
||||||
|
|
||||||
use crate::internal::state::AppState;
|
|
||||||
|
|
||||||
pub fn start_wayland() -> AppState {
|
|
||||||
let conn = Connection::connect_to_env().unwrap();
|
|
||||||
let _ = conn.display();
|
|
||||||
|
|
||||||
let mut event_queue: EventQueue<AppState> = conn.new_event_queue();
|
|
||||||
let _ = event_queue.handle();
|
|
||||||
|
|
||||||
let mut state = AppState::new();
|
|
||||||
|
|
||||||
// attach globals here (workspace manager bind happens via registry in real impl)
|
|
||||||
|
|
||||||
loop {
|
|
||||||
event_queue.blocking_dispatch(&mut state).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
use wayland_client::{Dispatch, QueueHandle};
|
|
||||||
use crate::internal::wayland::ext_workspace::ext_workspace_handle_v1::State;
|
|
||||||
use crate::internal::state::AppState;
|
|
||||||
use crate::api::model::Workspace;
|
|
||||||
use wayland_client::Proxy;
|
|
||||||
use wayland_client::WEnum;
|
|
||||||
use crate::internal::wayland::ext_workspace::{
|
|
||||||
ext_workspace_manager_v1,
|
|
||||||
ext_workspace_handle_v1,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl Dispatch<ext_workspace_manager_v1::ExtWorkspaceManagerV1, ()> for AppState {
|
|
||||||
fn event(
|
|
||||||
state: &mut Self,
|
|
||||||
_: &ext_workspace_manager_v1::ExtWorkspaceManagerV1,
|
|
||||||
event: ext_workspace_manager_v1::Event,
|
|
||||||
_: &(),
|
|
||||||
_: &wayland_client::Connection,
|
|
||||||
_: &QueueHandle<Self>,
|
|
||||||
) {
|
|
||||||
match event {
|
|
||||||
ext_workspace_manager_v1::Event::Workspace { workspace } => {
|
|
||||||
state.workspaces.insert(
|
|
||||||
workspace.id().to_string(),
|
|
||||||
Workspace {
|
|
||||||
id: None,
|
|
||||||
name: String::new(),
|
|
||||||
active: false,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Dispatch<ext_workspace_handle_v1::ExtWorkspaceHandleV1, ()> for AppState {
|
|
||||||
fn event(
|
|
||||||
state: &mut Self,
|
|
||||||
proxy: &ext_workspace_handle_v1::ExtWorkspaceHandleV1,
|
|
||||||
event: ext_workspace_handle_v1::Event,
|
|
||||||
_: &(),
|
|
||||||
_: &wayland_client::Connection,
|
|
||||||
_: &QueueHandle<Self>,
|
|
||||||
) {
|
|
||||||
let ws = state.workspaces.get_mut(&proxy.id().to_string());
|
|
||||||
|
|
||||||
if let Some(ws) = ws {
|
|
||||||
match event {
|
|
||||||
ext_workspace_handle_v1::Event::Name { name } => {
|
|
||||||
ws.name = name;
|
|
||||||
}
|
|
||||||
ext_workspace_handle_v1::Event::Id { id } => {
|
|
||||||
ws.id = Some(id);
|
|
||||||
}
|
|
||||||
ext_workspace_handle_v1::Event::State { state: flags } => {
|
|
||||||
ws.active = matches!(flags, WEnum::Value(State::Active));
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
use wayland_client;
|
|
||||||
use wayland_client::protocol::wl_output;
|
|
||||||
|
|
||||||
pub mod __interfaces {
|
|
||||||
use wayland_client::protocol::__interfaces::*;
|
|
||||||
|
|
||||||
wayland_scanner::generate_interfaces!(
|
|
||||||
"./protocols/ext-workspace-v1.xml"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
use self::__interfaces::*;
|
|
||||||
|
|
||||||
wayland_scanner::generate_client_code!(
|
|
||||||
"./protocols/ext-workspace-v1.xml"
|
|
||||||
);
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
pub mod connection;
|
|
||||||
pub mod events;
|
|
||||||
pub mod ext_workspace;
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue