Skip to content

Commit

Permalink
[KWin] Worked up the proof-of-concept to a slightly more polished ver…
Browse files Browse the repository at this point in the history
…sion (#143)
  • Loading branch information
flyingpie authored Oct 30, 2024
1 parent b523a11 commit 0159aa1
Show file tree
Hide file tree
Showing 34 changed files with 1,175 additions and 754 deletions.
6 changes: 1 addition & 5 deletions src/10-Core/Wtq/WtqApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,6 @@ public async Task CloseAsync(ToggleModifiers mods = ToggleModifiers.None)
// Move window off-screen.
await _toggler.ToggleOffAsync(this, mods).NoCtx();

// Hide window.
await Window.SetVisibleAsync(false).NoCtx();

await UpdateWindowPropsAsync().NoCtx();
}

Expand Down Expand Up @@ -206,8 +203,7 @@ public async Task<bool> OpenAsync(ToggleModifiers mods = ToggleModifiers.None)
return false;
}

// Make sure the app window is visible and has focus.
await Window.SetVisibleAsync(true).NoCtx();
// Make sure the app has focus.
await Window.BringToForegroundAsync().NoCtx();

// Move app onto screen.
Expand Down
2 changes: 0 additions & 2 deletions src/10-Core/Wtq/WtqWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ public abstract class WtqWindow

public abstract Task SetTransparencyAsync(int transparency);

public abstract Task SetVisibleAsync(bool isVisible);

public abstract Task SetWindowTitleAsync(string title);

public override string ToString() => $"[{Id}] {Name}";
Expand Down
77 changes: 48 additions & 29 deletions src/20-Services/Wtq.Services.KWin/DBus/DBusConnection.cs
Original file line number Diff line number Diff line change
@@ -1,63 +1,82 @@
using Tmds.DBus;
using Wtq.Exceptions;
using Address = Tmds.DBus.Protocol.Address;
using Connection = Tmds.DBus.Protocol.Connection;

namespace Wtq.Services.KWin.DBus;

/// <inheritdoc/>
public class DBusConnection : IDBusConnection
/// <inheritdoc cref="IDBusConnection"/>
internal sealed class DBusConnection : IAsyncInitializable, IDBusConnection
{
private readonly ILogger _log = Log.For<DBusConnection>();

/// <summary>
/// Client connection, used to send requests to DBus.
/// </summary>
private readonly Connection _clientConnection;

/// <summary>
/// Server connection, used to register DBus objects.
/// </summary>
private readonly Tmds.DBus.Connection _serverConnection;

private DBus.Generated.KWinService? _kwinService;
private DBus.Generated.KWin? _kwin;
private DBus.Generated.Scripting? _scripting;

public DBusConnection()
: this(Address.Session)
{
var address = Address.Session;
}

_log.LogInformation("Setting up DBus using address {Address}", address);
public DBusConnection(string? address)
{
Guard.Against.NullOrWhiteSpace(address);

if (string.IsNullOrWhiteSpace(address))
{
throw new WtqException("Could not determine address for session DBus.");
}
_log.LogInformation("Setting up DBus using address {Address}", address);

ClientConnection = new Connection(address);
ServerConnection = new Tmds.DBus.Connection(address);
_clientConnection = new Connection(address);
_serverConnection = new Tmds.DBus.Connection(address);
}

/// <inheritdoc/>
public Connection ClientConnection { get; }

/// <inheritdoc/>
public Tmds.DBus.Connection ServerConnection { get; }
public int InitializePriority => -20;

/// <summary>
/// Connects to DBus.
/// </summary>
public async Task StartAsync(CancellationToken cancellationToken)
public async Task InitializeAsync()
{
_log.LogInformation("Setting up DBus connections");

var sw = Stopwatch.StartNew();
await ClientConnection.ConnectAsync().NoCtx();
await _clientConnection.ConnectAsync().NoCtx();
_log.LogInformation("DBus client connection ready, took {Elapsed}", sw.Elapsed);

sw.Restart();
await ServerConnection.ConnectAsync().NoCtx();
await _serverConnection.ConnectAsync().NoCtx();
_log.LogInformation("DBus server connection ready, took {Elapsed}", sw.Elapsed);
}

public async Task<DBus.Generated.KWinService> GetKWinServiceAsync()
{
return _kwinService ??= new DBus.Generated.KWinService(_clientConnection, "org.kde.KWin");
}

public async Task<DBus.Generated.KWin> GetKWinAsync()
{
return _kwin ??= (await GetKWinServiceAsync().NoCtx()).CreateKWin("/KWin");
}

public async Task<DBus.Generated.Scripting> GetScriptingAsync()
{
return _scripting ??= (await GetKWinServiceAsync().NoCtx()).CreateScripting("/Scripting");
}

/// <summary>
/// Cleans up connections to DBus.
/// </summary>
public Task StopAsync(CancellationToken cancellationToken)
public void Dispose()
{
_log.LogInformation("Cleaning up DBus connections");

ClientConnection.Dispose();
ServerConnection.Dispose();

return Task.CompletedTask;
_clientConnection.Dispose();
_serverConnection.Dispose();
}

/// <inheritdoc/>
Expand All @@ -68,7 +87,7 @@ public async Task RegisterServiceAsync(string serviceName, IDBusObject serviceOb

_log.LogInformation("Registering DBus service with name '{ServiceName}', and object '{ServiceObject}'", serviceName, serviceObject);

await ServerConnection.RegisterServiceAsync(serviceName).NoCtx();
await ServerConnection.RegisterObjectAsync(serviceObject).NoCtx();
await _serverConnection.RegisterServiceAsync(serviceName).NoCtx();
await _serverConnection.RegisterObjectAsync(serviceObject).NoCtx();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma warning disable

namespace Wtq.Services.KWin.DBus;
namespace Wtq.Services.KWin.DBus.Generated;

using System;
using Tmds.DBus.Protocol;
Expand Down
15 changes: 5 additions & 10 deletions src/20-Services/Wtq.Services.KWin/DBus/IDBusConnection.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
using Tmds.DBus;
using Connection = Tmds.DBus.Protocol.Connection;

namespace Wtq.Services.KWin.DBus;

/// <summary>
/// Wraps both a client- and a server connection to DBus.<br/>
/// The client connection is used for sending requests to DBus, the server one is used to register DBus object.
/// </summary>
public interface IDBusConnection
internal interface IDBusConnection : IDisposable
{
/// <summary>
/// Client connection, used to send requests to DBus.
/// </summary>
Connection ClientConnection { get; }
Task<DBus.Generated.KWin> GetKWinAsync();

/// <summary>
/// Server connection, used to register DBus objects.
/// </summary>
Tmds.DBus.Connection ServerConnection { get; }
Task<DBus.Generated.KWinService> GetKWinServiceAsync();

Task<DBus.Generated.Scripting> GetScriptingAsync();

/// <summary>
/// Register an object that exposes methods that can be called by other processes.
Expand Down
19 changes: 13 additions & 6 deletions src/20-Services/Wtq.Services.KWin/DBus/IWtqDBusObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,23 @@ namespace Wtq.Services.KWin.DBus;
/// Contains methods used to talk to, from KWin scripts.
/// </summary>
[DBusInterface("wtq.kwin")]
public interface IWtqDBusObject : IDBusObject
public interface IWtqDBusObject : IDBusObject, IDisposable
{
Task LogAsync(string level, string msg);

/// <summary>
/// Called when a shortcut has been pressed.
/// Responses to commands (as passed through <seealso cref="GetNextCommandAsync"/>), are dropped here.
/// </summary>
Task OnPressShortcutAsync(string modStr, string keyStr);
Task SendResponseAsync(string respInfoStr);

/// <summary>
/// Ask WTQ for the next command to execute in the KWin script.
/// </summary>
Task<string> GetNextCommandAsync();

/// <summary>
/// Generic callback handler, responses are formatted as JSON.
/// Called when a shortcut has been pressed.<br/>
/// TODO: Would like to remove this, and do shortcuts through DBus (without KWin script). Didn't get that working just yet.
/// </summary>
/// TODO: Can we drop the request/response thing and move to pure events?
Task SendResponseAsync(string responderIdStr, string payloadJson);
Task OnPressShortcutAsync(string modStr, string keyStr);
}
Loading

0 comments on commit 0159aa1

Please sign in to comment.