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_root: 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:flutter_riverpod/flutter_riverpod.dart";
|
||||
|
||||
class WorkspacesController extends StreamNotifier<List<Workspace>> {
|
||||
@override
|
||||
Stream<List<Workspace>> build() => startWorkspaceStream();
|
||||
Stream<List<Workspace>> build() => listenWorkspaces();
|
||||
|
||||
static final provider =
|
||||
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
|
||||
|
||||
import '../frb_generated.dart';
|
||||
import 'model.dart';
|
||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||
|
||||
Stream<List<Workspace>> startWorkspaceStream() =>
|
||||
RustLib.instance.api.crateApiWorkspaceApiStartWorkspaceStream();
|
||||
// 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`
|
||||
|
||||
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
|
||||
|
||||
import 'api/model.dart';
|
||||
import 'api/workspace_api.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
|
@ -65,7 +64,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
|||
String get codegenVersion => '2.11.1';
|
||||
|
||||
@override
|
||||
int get rustContentHash => 804335101;
|
||||
int get rustContentHash => 1397669831;
|
||||
|
||||
static const kDefaultExternalLibraryLoaderConfig =
|
||||
ExternalLibraryLoaderConfig(
|
||||
|
|
@ -76,7 +75,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
|||
}
|
||||
|
||||
abstract class RustLibApi extends BaseApi {
|
||||
Stream<List<Workspace>> crateApiWorkspaceApiStartWorkspaceStream();
|
||||
Stream<List<Workspace>> crateApiWorkspaceApiListenWorkspaces();
|
||||
}
|
||||
|
||||
class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
|
|
@ -88,7 +87,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||
});
|
||||
|
||||
@override
|
||||
Stream<List<Workspace>> crateApiWorkspaceApiStartWorkspaceStream() {
|
||||
Stream<List<Workspace>> crateApiWorkspaceApiListenWorkspaces() {
|
||||
final sink = RustStreamSink<List<Workspace>>();
|
||||
unawaited(
|
||||
handler.executeNormal(
|
||||
|
|
@ -105,9 +104,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||
},
|
||||
codec: SseCodec(
|
||||
decodeSuccessData: sse_decode_unit,
|
||||
decodeErrorData: null,
|
||||
decodeErrorData: sse_decode_AnyhowException,
|
||||
),
|
||||
constMeta: kCrateApiWorkspaceApiStartWorkspaceStreamConstMeta,
|
||||
constMeta: kCrateApiWorkspaceApiListenWorkspacesConstMeta,
|
||||
argValues: [sink],
|
||||
apiImpl: this,
|
||||
),
|
||||
|
|
@ -116,11 +115,8 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||
return sink.stream;
|
||||
}
|
||||
|
||||
TaskConstMeta get kCrateApiWorkspaceApiStartWorkspaceStreamConstMeta =>
|
||||
const TaskConstMeta(
|
||||
debugName: "start_workspace_stream",
|
||||
argNames: ["sink"],
|
||||
);
|
||||
TaskConstMeta get kCrateApiWorkspaceApiListenWorkspacesConstMeta =>
|
||||
const TaskConstMeta(debugName: "listen_workspaces", argNames: ["sink"]);
|
||||
|
||||
@protected
|
||||
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();
|
||||
}
|
||||
|
||||
@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
|
||||
int dco_decode_u_8(dynamic raw) {
|
||||
// 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) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
final arr = raw as List<dynamic>;
|
||||
if (arr.length != 3)
|
||||
throw Exception('unexpected arr length: expect 3 but see ${arr.length}');
|
||||
return Workspace(
|
||||
id: dco_decode_opt_String(arr[0]),
|
||||
name: dco_decode_String(arr[1]),
|
||||
active: dco_decode_bool(arr[2]),
|
||||
);
|
||||
if (arr.length != 1)
|
||||
throw Exception('unexpected arr length: expect 1 but see ${arr.length}');
|
||||
return Workspace(activated: dco_decode_bool(arr[0]));
|
||||
}
|
||||
|
||||
@protected
|
||||
|
|
@ -238,17 +224,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||
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
|
||||
int sse_decode_u_8(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
|
|
@ -263,10 +238,8 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||
@protected
|
||||
Workspace sse_decode_workspace(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
var var_id = sse_decode_opt_String(deserializer);
|
||||
var var_name = sse_decode_String(deserializer);
|
||||
var var_active = sse_decode_bool(deserializer);
|
||||
return Workspace(id: var_id, name: var_name, active: var_active);
|
||||
var var_activated = sse_decode_bool(deserializer);
|
||||
return Workspace(activated: var_activated);
|
||||
}
|
||||
|
||||
@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
|
||||
void sse_encode_u_8(int self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
|
|
@ -359,9 +322,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||
@protected
|
||||
void sse_encode_workspace(Workspace self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
sse_encode_opt_String(self.id, serializer);
|
||||
sse_encode_String(self.name, serializer);
|
||||
sse_encode_bool(self.active, serializer);
|
||||
sse_encode_bool(self.activated, serializer);
|
||||
}
|
||||
|
||||
@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
|
||||
|
||||
import 'api/model.dart';
|
||||
import 'api/workspace_api.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
|
@ -39,9 +38,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||
@protected
|
||||
List<Workspace> dco_decode_list_workspace(dynamic raw);
|
||||
|
||||
@protected
|
||||
String? dco_decode_opt_String(dynamic raw);
|
||||
|
||||
@protected
|
||||
int dco_decode_u_8(dynamic raw);
|
||||
|
||||
|
|
@ -71,9 +67,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||
@protected
|
||||
List<Workspace> sse_decode_list_workspace(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
String? sse_decode_opt_String(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int sse_decode_u_8(SseDeserializer deserializer);
|
||||
|
||||
|
|
@ -116,9 +109,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||
SseSerializer serializer,
|
||||
);
|
||||
|
||||
@protected
|
||||
void sse_encode_opt_String(String? self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_u_8(int self, SseSerializer serializer);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
// Static analysis wrongly picks the IO variant, thus ignore this
|
||||
// ignore_for_file: argument_type_not_assignable
|
||||
|
||||
import 'api/model.dart';
|
||||
import 'api/workspace_api.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
|
@ -41,9 +40,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||
@protected
|
||||
List<Workspace> dco_decode_list_workspace(dynamic raw);
|
||||
|
||||
@protected
|
||||
String? dco_decode_opt_String(dynamic raw);
|
||||
|
||||
@protected
|
||||
int dco_decode_u_8(dynamic raw);
|
||||
|
||||
|
|
@ -73,9 +69,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||
@protected
|
||||
List<Workspace> sse_decode_list_workspace(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
String? sse_decode_opt_String(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int sse_decode_u_8(SseDeserializer deserializer);
|
||||
|
||||
|
|
@ -118,9 +111,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||
SseSerializer serializer,
|
||||
);
|
||||
|
||||
@protected
|
||||
void sse_encode_opt_String(String? self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
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/workspaces_controller.dart';
|
||||
import 'package:flight/widgets/loading.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
|
@ -24,18 +27,24 @@ class Bar extends ConsumerWidget {
|
|||
ref
|
||||
.watch(WorkspacesController.provider)
|
||||
.whenOrNull(
|
||||
data: (value) => value
|
||||
error: (error, stackTrace) => [
|
||||
Text(error.toString()),
|
||||
],
|
||||
loading: () => [Text("loading")],
|
||||
data: (value) {
|
||||
return value
|
||||
.map(
|
||||
(element) => IconButton(
|
||||
onPressed: () {},
|
||||
icon: Icon(
|
||||
element.active
|
||||
element.activated
|
||||
? Icons.circle
|
||||
: Icons.circle_outlined,
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
.toList();
|
||||
},
|
||||
) ??
|
||||
[],
|
||||
[
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ pkgs.mkShell {
|
|||
gtk-layer-shell
|
||||
|
||||
cargo
|
||||
rustfmt
|
||||
flutter_rust_bridge_codegen
|
||||
(pkgs.writeShellScriptBin "rustup" (builtins.readFile ./fake-rustup.sh))
|
||||
|
||||
|
|
|
|||
|
|
@ -7,12 +7,11 @@ edition = "2021"
|
|||
crate-type = ["cdylib", "staticlib"]
|
||||
|
||||
[dependencies]
|
||||
wayland-scanner = "0.31"
|
||||
flutter_rust_bridge = "=2.11.1"
|
||||
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
|
||||
futures = "0.3"
|
||||
|
||||
wayland-client = "0.31"
|
||||
wayland-scanner = "0.31"
|
||||
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
|
|
|
|||
|
|
@ -1,2 +1 @@
|
|||
pub mod model;
|
||||
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 crate::api::model::Workspace;
|
||||
use serde_json::Result;
|
||||
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 || {
|
||||
// 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 {
|
||||
// Replace with real shared state later
|
||||
let data = vec![];
|
||||
|
||||
sink.add(data).ok();
|
||||
|
||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
event_queue
|
||||
.blocking_dispatch(&mut state)
|
||||
.expect("Wayland dispatch failed");
|
||||
}
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ flutter_rust_bridge::frb_generated_boilerplate!(
|
|||
default_rust_auto_opaque = RustAutoOpaqueMoi,
|
||||
);
|
||||
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
|
||||
|
|
@ -46,13 +46,13 @@ flutter_rust_bridge::frb_generated_default_handler!();
|
|||
|
||||
// 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) {
|
||||
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 || {
|
||||
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: "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 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| {
|
||||
transform_result_sse::<_, ()>((move || {
|
||||
let output_ok = Result::<_,()>::Ok({ crate::api::workspace_api::start_workspace_stream(api_sink); })?; Ok(output_ok)
|
||||
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::<_, flutter_rust_bridge::for_generated::anyhow::Error>((move || {
|
||||
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);}
|
||||
}
|
||||
|
||||
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
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {let mut inner = <String>::sse_decode(deserializer);
|
||||
return StreamSink::deserialize(inner);}
|
||||
|
|
@ -91,23 +91,14 @@ fn wire__crate__api__workspace_api__start_workspace_stream_impl(port_: flutter_r
|
|||
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
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {let mut len_ = <i32>::sse_decode(deserializer);
|
||||
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_;}
|
||||
}
|
||||
|
||||
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 {
|
||||
// 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()}
|
||||
|
|
@ -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 {}
|
||||
}
|
||||
|
||||
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
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {let mut var_id = <Option<String>>::sse_decode(deserializer);
|
||||
let mut var_name = <String>::sse_decode(deserializer);
|
||||
let mut var_active = <bool>::sse_decode(deserializer);
|
||||
return crate::api::model::Workspace{id: var_id, name: var_name, active: var_active};}
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {let mut var_activated = <bool>::sse_decode(deserializer);
|
||||
return crate::api::workspace_api::Workspace{activated: var_activated};}
|
||||
}
|
||||
|
||||
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
|
||||
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!(),
|
||||
}
|
||||
}
|
||||
|
|
@ -161,18 +150,16 @@ return crate::api::model::Workspace{id: var_id, name: var_name, active: var_acti
|
|||
// Section: rust2dart
|
||||
|
||||
// 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 {
|
||||
[
|
||||
self.id.into_into_dart().into_dart(),
|
||||
self.name.into_into_dart().into_dart(),
|
||||
self.active.into_into_dart().into_dart()
|
||||
self.activated.into_into_dart().into_dart()
|
||||
].into_dart()
|
||||
}
|
||||
}
|
||||
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::api::model::Workspace {}
|
||||
impl flutter_rust_bridge::IntoIntoDart<crate::api::model::Workspace> for crate::api::model::Workspace {
|
||||
fn into_into_dart(self) -> crate::api::model::Workspace {
|
||||
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::api::workspace_api::Workspace {}
|
||||
impl flutter_rust_bridge::IntoIntoDart<crate::api::workspace_api::Workspace> for crate::api::workspace_api::Workspace {
|
||||
fn into_into_dart(self) -> crate::api::workspace_api::Workspace {
|
||||
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);}
|
||||
}
|
||||
|
||||
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
|
||||
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); }}
|
||||
}
|
||||
|
||||
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
|
||||
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); }}
|
||||
}
|
||||
|
||||
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);
|
||||
}}
|
||||
for item in self { <crate::api::workspace_api::Workspace>::sse_encode(item, serializer); }}
|
||||
}
|
||||
|
||||
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) {}
|
||||
}
|
||||
|
||||
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
|
||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {<Option<String>>::sse_encode(self.id, serializer);
|
||||
<String>::sse_encode(self.name, serializer);
|
||||
<bool>::sse_encode(self.active, serializer);}
|
||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {<bool>::sse_encode(self.activated, serializer);}
|
||||
}
|
||||
|
||||
impl SseEncode for i32 {
|
||||
|
|
|
|||
|
|
@ -1,2 +1 @@
|
|||
pub mod state;
|
||||
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