refacto API prefix + nav.back
This commit is contained in:
parent
bd6ca9d11f
commit
6825f74308
78 changed files with 770 additions and 222 deletions
137
src/PostIt.Tests/AddCircleMemberDialogTests.cs
Normal file
137
src/PostIt.Tests/AddCircleMemberDialogTests.cs
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Headless.XUnit;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using PostIt.Services;
|
||||
using PostIt.ViewModels;
|
||||
using PostIt.Views;
|
||||
using Yavsc.Api.Client;
|
||||
|
||||
namespace PostIt.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Headless coverage for the two interactive buttons of the
|
||||
/// "add a circle member" modal: "Ajouter" and "Fermer".
|
||||
///
|
||||
/// <para>The dialog is pushed on top of <see cref="CirclesPage"/>
|
||||
/// via the canonical <c>App.PushPageAsync</c> pipeline (the
|
||||
/// same path <c>CirclesPageViewModel.OpenAddMemberAsync</c>
|
||||
/// uses). The test asserts on <c>NavRoot.NavigationStack</c>
|
||||
/// size before and after each click — the user's bug was "I
|
||||
/// click and nothing happens", so the failure mode is a stack
|
||||
/// that doesn't shrink for "Fermer", and a "Confirmer" event
|
||||
/// that the host doesn't pick up for "Ajouter" (the dialog
|
||||
/// stays up = stack doesn't shrink either).</para>
|
||||
///
|
||||
/// <para>Pattern follows <c>MainPageButtonsTests</c>: name
|
||||
/// every interactive control in XAML with <c>x:Name</c>,
|
||||
/// click via <c>button.Command?.Execute(...)</c> + flush
|
||||
/// any async command before asserting.</para>
|
||||
/// </summary>
|
||||
public class AddCircleMemberDialogTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Stand-in <see cref="IUserDirectory"/> that returns an
|
||||
/// empty list. The dialog's "Rechercher" button is never
|
||||
/// exercised in these tests — the picker starts empty and
|
||||
/// the "Ajouter" button's IsEnabled is bound to a null
|
||||
/// selection, which keeps the click harmless even when
|
||||
/// its <see cref="AddCircleMemberDialogViewModel.Add"/>
|
||||
/// command does fire.
|
||||
/// </summary>
|
||||
private sealed class StubUserDirectory : IUserDirectory
|
||||
{
|
||||
public Task<IReadOnlyList<UserSummary>> SearchAsync(string query, CancellationToken ct = default)
|
||||
=> Task.FromResult<IReadOnlyList<UserSummary>>(new List<UserSummary>());
|
||||
}
|
||||
|
||||
private sealed class ThrowingApi : YavscApiClient
|
||||
{
|
||||
public ThrowingApi() : base(
|
||||
new Settings
|
||||
{
|
||||
Authentication = new AuthenticationSettings
|
||||
{
|
||||
Authority = "https://stub.invalid",
|
||||
ClientId = "stub",
|
||||
Scopes = new[] { "openid" },
|
||||
},
|
||||
},
|
||||
new TokenStore(System.IO.Path.GetTempFileName()))
|
||||
{ }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mount a real <see cref="MainWindow"/>, build a minimal
|
||||
/// DI graph, push <see cref="CirclesPage"/> then the
|
||||
/// <see cref="AddCircleMemberDialog"/> on top of it.
|
||||
/// Returns the stack size so the test can pin the delta.
|
||||
/// The graph exposes <c>IUserDirectory</c> (so the dialog
|
||||
/// VM resolves its dependency) and <c>AddCircleMemberDialog</c>
|
||||
/// (so <c>ViewLocator</c> can resolve it from the VM).
|
||||
/// </summary>
|
||||
private static (MainWindow window, CirclesPage page, AddCircleMemberDialog dialog) Mount()
|
||||
{
|
||||
var api = new ThrowingApi();
|
||||
var circleClient = new CircleApiClient(api, "http://localhost/");
|
||||
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton(new Settings());
|
||||
services.AddSingleton<IUserDirectory>(new StubUserDirectory());
|
||||
services.AddSingleton(circleClient);
|
||||
services.AddTransient<CirclesPage>();
|
||||
services.AddTransient<CirclesPageViewModel>();
|
||||
services.AddTransient<AddCircleMemberDialog>();
|
||||
services.AddTransient<AddCircleMemberDialogViewModel>();
|
||||
var sp = services.BuildServiceProvider();
|
||||
|
||||
var window = new MainWindow();
|
||||
var app = (PostIt.App)Application.Current!;
|
||||
app.DataTemplates.Clear();
|
||||
app.DataTemplates.Add(new ViewLocator(sp));
|
||||
app.AttachMainWindow(window);
|
||||
window.Show();
|
||||
|
||||
var circlesPage = sp.GetRequiredService<CirclesPage>();
|
||||
window.NavRoot.PushAsync(circlesPage).GetAwaiter().GetResult();
|
||||
|
||||
// The "Ajouter un membre" command on CirclesPage builds
|
||||
// the dialog VM directly (it knows the directory from
|
||||
// the service provider) and pushes it via App.PushPage.
|
||||
var dialogVm = new AddCircleMemberDialogViewModel(sp.GetRequiredService<IUserDirectory>());
|
||||
((App)Application.Current!).PushPageAsync(dialogVm).GetAwaiter().GetResult();
|
||||
|
||||
var dialog = window.NavRoot.NavigationStack[^1] as AddCircleMemberDialog
|
||||
?? throw new System.InvalidOperationException("Dialog page not at top of stack.");
|
||||
return (window, circlesPage, dialog);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Click the "Fermer" button on the dialog and assert the
|
||||
/// nav stack shrinks by exactly one.
|
||||
/// </summary>
|
||||
[AvaloniaFact]
|
||||
public void Close_button_pops_dialog_off_nav_stack()
|
||||
{
|
||||
// Arrange: stack starts at 2 (CirclesPage + dialog).
|
||||
var (window, _, _) = Mount();
|
||||
var stackBefore = window.NavRoot.NavigationStack.Count;
|
||||
Assert.Equal(2, stackBefore);
|
||||
|
||||
// Act
|
||||
var dialog = window.NavRoot.NavigationStack[^1] as AddCircleMemberDialog ?? throw new System.InvalidOperationException();
|
||||
// The "Fermer" button uses a Click handler (not a
|
||||
// Command), so RaiseEvent(Button.ClickEvent) is the
|
||||
// right way to fire it from headless code. Executing
|
||||
// Command would no-op because no Command is bound.
|
||||
dialog.CloseButton.RaiseEvent(new Avalonia.Interactivity.RoutedEventArgs(Button.ClickEvent));
|
||||
|
||||
// Assert: stack -1, the top is the CirclesPage again.
|
||||
Assert.True(window.NavRoot.NavigationStack.Count == stackBefore - 1,
|
||||
$"Click on 'Fermer' must shrink the nav stack by one. Before: {stackBefore}, after: {window.NavRoot.NavigationStack.Count}.");
|
||||
Assert.IsType<CirclesPage>(window.NavRoot.NavigationStack[^1]);
|
||||
}
|
||||
}
|
||||
234
src/PostIt.Tests/PostAclDialogTests.cs
Normal file
234
src/PostIt.Tests/PostAclDialogTests.cs
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Headless.XUnit;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using PostIt.Services;
|
||||
using PostIt.ViewModels;
|
||||
using PostIt.Views;
|
||||
using Yavsc.Abstract.Identity.Security;
|
||||
using Yavsc.Api.Client;
|
||||
using Yavsc.Api.Client.Dtos;
|
||||
using Yavsc.Blogspot;
|
||||
|
||||
namespace PostIt.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Regression coverage for the user-reported bug:
|
||||
/// <c>PostAclDialogViewModel.LoadAsync</c> was never invoked,
|
||||
/// so <c>MyCircles</c> and <c>AclEntries</c> were empty when the
|
||||
/// dialog opened (the dropdown showed "Choisir un cercle..." and
|
||||
/// the list was blank, with no error to hint at why).
|
||||
///
|
||||
/// <para>The fix wires <see cref="PostAclDialog"/>'s constructor
|
||||
/// to trigger <c>LoadAsync</c> on the first
|
||||
/// <c>AttachedToVisualTree</c>, and the VM guards re-entry via
|
||||
/// <c>_loaded</c>. Two tests pin that contract:</para>
|
||||
/// <list type="bullet">
|
||||
/// <item><c>LoadAsync_runs_once_on_visual_attachment</c>: HTTP
|
||||
/// traffic shows up after the dialog is mounted.</item>
|
||||
/// <item><c>LoadAsync_is_idempotent</c>: a second explicit call
|
||||
/// to <c>LoadAsync</c> on the same VM hits the HTTP layer only
|
||||
/// once (the <c>_loaded</c> gate).</item>
|
||||
/// </list>
|
||||
///
|
||||
/// <para>HTTP is stubbed with a counter
|
||||
/// <see cref="HttpMessageHandler"/> that returns canned JSON
|
||||
/// <c>[]</c> for every request. The handler counts calls so the
|
||||
/// tests can assert "exactly one round-trip on mount" and
|
||||
/// "exactly one round-trip after two calls to LoadAsync". This
|
||||
/// is the same shape used by <c>BearerScopeTests</c>: real
|
||||
/// <see cref="YavscApiClient"/> subclass, real
|
||||
/// <see cref="HttpClient"/> with an injected handler, real
|
||||
/// <see cref="BlogAclApiClient"/> / <see cref="CircleApiClient"/>
|
||||
/// talking to it.</para>
|
||||
/// </summary>
|
||||
public class PostAclDialogTests
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="HttpMessageHandler"/> that replies 200 with
|
||||
/// <c>[]</c> (a valid JSON empty array, which both
|
||||
/// <c>GetMyAclAsync</c> and <c>GetMyCirclesAsync</c> can
|
||||
/// deserialize) and counts the number of requests.
|
||||
/// </summary>
|
||||
private sealed class CountingHttpHandler : HttpMessageHandler
|
||||
{
|
||||
public int RequestCount { get; private set; }
|
||||
|
||||
protected override Task<HttpResponseMessage> SendAsync(
|
||||
HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
RequestCount++;
|
||||
var response = new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StringContent("[]", Encoding.UTF8, "application/json"),
|
||||
};
|
||||
return Task.FromResult(response);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subclass of <see cref="YavscApiClient"/> that routes HTTP
|
||||
/// traffic through a caller-supplied
|
||||
/// <see cref="HttpMessageHandler"/>. Same recipe as
|
||||
/// <c>BearerScopeTests.TestableYavscApiClient</c> — we
|
||||
/// override <c>CallAsync{T}</c> to talk to our own
|
||||
/// <see cref="HttpClient"/> and skip the OIDC refresh path,
|
||||
/// because the load-on-attach bug has nothing to do with
|
||||
/// token refresh.
|
||||
/// </summary>
|
||||
private sealed class TestableYavscApiClient : YavscApiClient
|
||||
{
|
||||
private readonly HttpClient _http;
|
||||
|
||||
public TestableYavscApiClient(
|
||||
Settings settings,
|
||||
TokenStore store,
|
||||
HttpMessageHandler handler)
|
||||
: base(settings, store, oidc: null!)
|
||||
{
|
||||
_http = new HttpClient(handler, disposeHandler: false);
|
||||
}
|
||||
|
||||
public override Task<T> CallAsync<T>(
|
||||
HttpMethod method, string path, object? body = null,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
var absolute = new Uri(new Uri(Settings.BusinessApiUrl), path);
|
||||
using var req = new HttpRequestMessage(method, absolute);
|
||||
using var resp = _http.SendAsync(req, ct).GetAwaiter().GetResult();
|
||||
resp.EnsureSuccessStatusCode();
|
||||
using var stream = resp.Content.ReadAsStream();
|
||||
var dto = JsonSerializer.Deserialize<T>(stream,
|
||||
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
||||
return Task.FromResult(dto!);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build a minimal DI graph exposing the two API clients
|
||||
/// (backed by a stub HTTP handler) and the page itself, so
|
||||
/// <c>ViewLocator</c> can resolve the dialog from the VM.
|
||||
/// Returns the handler, the API clients, and the window so
|
||||
/// the test can assert on request counts and push the
|
||||
/// dialog via the canonical <c>App.PushPageAsync</c> path.
|
||||
/// The DI graph is built into a local <see cref="IServiceProvider"/>
|
||||
/// that is NOT attached to <see cref="App.ServiceProvider"/>:
|
||||
/// rebinding the global DI mid-test would trample the
|
||||
/// Settings singleton the rest of the harness depends on.
|
||||
/// </summary>
|
||||
private static (MainWindow window, BlogAclApiClient aclClient, CircleApiClient circleClient, CountingHttpHandler handler) Mount()
|
||||
{
|
||||
var handler = new CountingHttpHandler();
|
||||
var settings = new Settings();
|
||||
var api = new TestableYavscApiClient(settings, new TokenStore(System.IO.Path.GetTempFileName()), handler);
|
||||
var aclClient = new BlogAclApiClient(api, settings.BusinessApiUrl);
|
||||
var circleClient = new CircleApiClient(api, settings.BusinessApiUrl);
|
||||
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton(settings);
|
||||
services.AddSingleton(api);
|
||||
services.AddSingleton(aclClient);
|
||||
services.AddSingleton(circleClient);
|
||||
services.AddTransient<PostAclDialog>();
|
||||
var sp = services.BuildServiceProvider();
|
||||
// Hold the sp alive for the test scope; otherwise the
|
||||
// GC could collect the singletons between Mount() and
|
||||
// the assertion below, and we'd lose the wiring to the
|
||||
// CountingHttpHandler.
|
||||
GC.KeepAlive(sp);
|
||||
|
||||
var window = new MainWindow();
|
||||
var app = (App)Application.Current!;
|
||||
app.DataTemplates.Clear();
|
||||
app.DataTemplates.Add(new ViewLocator(sp));
|
||||
app.AttachMainWindow(window);
|
||||
window.Show();
|
||||
|
||||
return (window, aclClient, circleClient, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The bug: opening the dialog never called LoadAsync, so
|
||||
/// MyCircles/AclEntries were empty. After the fix, setting
|
||||
/// the dialog's DataContext to a PostAclDialogViewModel
|
||||
/// (the same path App.PushPageAsync takes) must trigger
|
||||
/// exactly one LoadAsync round-trip (the parallel WhenAll
|
||||
/// inside the VM counts as one request per backend call,
|
||||
/// hence two HTTP requests total: GET /blogacl and GET
|
||||
/// /circle).
|
||||
/// </summary>
|
||||
[AvaloniaFact]
|
||||
public async Task LoadAsync_runs_once_on_DataContext_changed()
|
||||
{
|
||||
// Arrange
|
||||
var (window, aclClient, circleClient, handler) = Mount();
|
||||
var post = new BlogPostDto { Id = 42, Title = "Test post" };
|
||||
|
||||
// Sanity: handler starts quiet.
|
||||
Assert.Equal(0, handler.RequestCount);
|
||||
|
||||
// Act: push the dialog via the canonical VM-first pipeline.
|
||||
// The locator goes through the parameterless ctor of
|
||||
// PostAclDialog, then App.PushPageAsync assigns DataContext,
|
||||
// which our hook intercepts to trigger LoadAsync.
|
||||
var vm = new PostAclDialogViewModel(post, aclClient, circleClient);
|
||||
await ((App)Application.Current!).PushPageAsync(vm);
|
||||
|
||||
// The dialog must be at the top of the nav stack and
|
||||
// have its VM as DataContext.
|
||||
var dialog = window.NavRoot.NavigationStack[^1] as PostAclDialog
|
||||
?? throw new InvalidOperationException("Dialog not at top of stack");
|
||||
Assert.Same(vm, dialog.DataContext);
|
||||
|
||||
// Drain pending async work. LoadAsync is async and the
|
||||
// DataContextChanged handler is fire-and-forget; a
|
||||
// couple of loop turns is enough. We poll the handler
|
||||
// counter because the dispatch back onto the headless
|
||||
// dispatcher isn't strict — using a generous-but-bounded
|
||||
// wait avoids test flakes.
|
||||
var deadline = DateTime.UtcNow.AddSeconds(2);
|
||||
while (handler.RequestCount < 2 && DateTime.UtcNow < deadline)
|
||||
{
|
||||
await Task.Delay(20);
|
||||
}
|
||||
|
||||
// Assert: exactly two GETs went out (one to /blogacl,
|
||||
// one to /circle), both from the LoadAsync call.
|
||||
Assert.Equal(2, handler.RequestCount);
|
||||
|
||||
// And the VM's idempotency gate has flipped.
|
||||
Assert.True(vm.Loaded);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The fix exposes a guard on the VM too: a second call to
|
||||
/// LoadAsync on the same instance must NOT issue more HTTP
|
||||
/// traffic. This protects against the
|
||||
/// DataContextChanged-firing-twice case (DataContext
|
||||
/// overwritten mid-life, edge cases in dialog re-use).
|
||||
/// </summary>
|
||||
[AvaloniaFact]
|
||||
public async Task LoadAsync_is_idempotent()
|
||||
{
|
||||
// Arrange
|
||||
var (_, aclClient, circleClient, handler) = Mount();
|
||||
var post = new BlogPostDto { Id = 99, Title = "Idempotency" };
|
||||
var vm = new PostAclDialogViewModel(post, aclClient, circleClient);
|
||||
|
||||
// Act: invoke LoadAsync twice in a row.
|
||||
await vm.LoadAsync();
|
||||
await vm.LoadAsync();
|
||||
|
||||
// Assert: the second call short-circuited on _loaded.
|
||||
Assert.Equal(2, handler.RequestCount);
|
||||
Assert.True(vm.Loaded);
|
||||
}
|
||||
}
|
||||
94
src/PostIt.Tests/pslist
Normal file
94
src/PostIt.Tests/pslist
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
UID PID PPID C STIME TTY TIME CMD
|
||||
paul 1155 1 0 13:18 ? 00:00:00 /usr/lib/systemd/systemd --user
|
||||
paul 1168 1155 0 13:18 ? 00:00:00 (sd-pam)
|
||||
paul 1361 1155 0 13:18 ? 00:00:00 /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
|
||||
paul 1364 1155 1 13:18 ? 00:01:19 /home/paul/.nvm/versions/node/v22.23.0/bin/node /home/paul/.nvm/versions/node/v22.23.0/lib/node_modules/openclaw/dist/index.js gateway --port 18789
|
||||
paul 1367 1155 0 13:18 ? 00:00:00 /usr/bin/pipewire
|
||||
paul 1372 1155 0 13:18 ? 00:00:00 /usr/bin/pipewire -c filter-chain.conf
|
||||
paul 1373 1155 0 13:18 ? 00:00:00 /usr/bin/wireplumber
|
||||
paul 1374 1155 0 13:18 ? 00:00:00 /usr/bin/pipewire-pulse
|
||||
paul 1444 1155 0 13:18 ? 00:00:00 /usr/bin/mpris-proxy
|
||||
paul 2593 1155 0 13:19 ? 00:00:00 /usr/bin/gnome-keyring-daemon --foreground --components=pkcs11,secrets --control-directory=/run/user/1000/keyring
|
||||
paul 2608 2487 0 13:19 tty2 00:00:00 /usr/libexec/gdm-x-session --run-script /usr/bin/gnome-session
|
||||
paul 2617 2608 1 13:19 tty2 00:01:12 /usr/lib/xorg/Xorg vt2 -displayfd 3 -auth /run/user/1000/gdm/Xauthority -nolisten tcp -background none -noreset -keeptty -novtswitch -verbose 3
|
||||
paul 2647 2608 0 13:19 tty2 00:00:00 /usr/libexec/gnome-session-binary
|
||||
paul 2785 1155 0 13:19 ? 00:00:00 /usr/libexec/at-spi-bus-launcher
|
||||
paul 2792 2785 0 13:19 ? 00:00:00 /usr/bin/dbus-daemon --config-file=/usr/share/defaults/at-spi2/accessibility.conf --nofork --print-address 11 --address=unix:path=/run/user/1000/at-spi/bus_1
|
||||
paul 2802 1155 0 13:19 ? 00:00:00 /usr/libexec/gcr-ssh-agent --base-dir /run/user/1000/gcr
|
||||
paul 2803 1155 0 13:19 ? 00:00:00 /usr/libexec/gnome-session-ctl --monitor
|
||||
paul 2804 1155 0 13:19 ? 00:00:00 /usr/bin/ssh-agent -D
|
||||
paul 2814 1155 0 13:19 ? 00:00:00 /usr/libexec/gvfsd
|
||||
paul 2828 1155 0 13:19 ? 00:00:00 /usr/libexec/gvfsd-fuse /run/user/1000/gvfs -f
|
||||
paul 2838 1155 0 13:19 ? 00:00:00 /usr/libexec/gnome-session-binary --systemd-service --session=gnome
|
||||
paul 2874 1155 3 13:19 ? 00:02:13 /usr/bin/gnome-shell
|
||||
paul 2896 2874 0 13:19 ? 00:00:01 /usr/libexec/mutter-x11-frames
|
||||
paul 2902 1155 0 13:19 ? 00:00:00 /usr/libexec/at-spi2-registryd --use-gnome-session
|
||||
paul 2918 1155 0 13:19 ? 00:00:00 /usr/libexec/xdg-desktop-portal
|
||||
paul 2933 1155 0 13:19 ? 00:00:00 /usr/libexec/xdg-permission-store
|
||||
paul 2938 1155 0 13:19 ? 00:00:00 /usr/libexec/xdg-document-portal
|
||||
paul 2971 1155 0 13:19 ? 00:00:00 /usr/libexec/gnome-shell-calendar-server
|
||||
paul 2976 1155 0 13:19 ? 00:00:00 /usr/libexec/dconf-service
|
||||
paul 2992 1155 0 13:19 ? 00:00:00 /usr/libexec/evolution-source-registry
|
||||
paul 2994 1155 0 13:19 ? 00:00:00 /usr/bin/gjs -m /usr/share/gnome-shell/org.gnome.Shell.Notifications
|
||||
paul 3012 1155 0 13:19 ? 00:00:12 /usr/bin/ibus-daemon --panel disable --xim
|
||||
paul 3013 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-a11y-settings
|
||||
paul 3014 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-color
|
||||
paul 3015 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-datetime
|
||||
paul 3016 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-housekeeping
|
||||
paul 3018 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-keyboard
|
||||
paul 3024 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-media-keys
|
||||
paul 3025 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-power
|
||||
paul 3027 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-print-notifications
|
||||
paul 3029 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-rfkill
|
||||
paul 3030 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-screensaver-proxy
|
||||
paul 3035 2838 0 13:19 ? 00:00:05 /usr/bin/gnome-software --gapplication-service
|
||||
paul 3037 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-sharing
|
||||
paul 3042 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-smartcard
|
||||
paul 3048 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-sound
|
||||
paul 3054 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-usb-protection
|
||||
paul 3057 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-wacom
|
||||
paul 3058 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-xsettings
|
||||
paul 3059 2838 0 13:19 ? 00:00:00 /usr/libexec/evolution-data-server/evolution-alarm-notify
|
||||
paul 3064 2838 0 13:19 ? 00:00:00 /usr/bin/kalendarac
|
||||
paul 3070 2838 0 13:19 ? 00:00:00 /usr/libexec/gsd-disk-utility-notify
|
||||
paul 3088 2838 0 13:19 ? 00:00:00 /usr/bin/kdeconnectd
|
||||
paul 3168 1155 0 13:19 ? 00:00:00 /usr/bin/gjs -m /usr/share/gnome-shell/org.gnome.ScreenSaver
|
||||
paul 3172 1155 0 13:19 ? 00:00:00 /usr/libexec/gsd-printer
|
||||
paul 3207 3012 0 13:19 ? 00:00:00 /usr/libexec/ibus-memconf
|
||||
paul 3208 3012 0 13:19 ? 00:00:06 /usr/libexec/ibus-extension-gtk3
|
||||
paul 3214 1155 0 13:19 ? 00:00:00 /usr/libexec/ibus-x11 --kill-daemon
|
||||
paul 3216 1155 0 13:19 ? 00:00:00 /usr/libexec/ibus-portal
|
||||
paul 3218 1155 0 13:19 ? 00:00:00 /usr/libexec/localsearch-3
|
||||
paul 3219 1155 0 13:19 ? 00:00:00 /usr/libexec/xdg-desktop-portal-gnome
|
||||
paul 3241 1155 0 13:19 ? 00:00:00 /usr/libexec/gvfs-udisks2-volume-monitor
|
||||
paul 3251 1155 0 13:19 ? 00:00:00 /usr/libexec/gvfs-mtp-volume-monitor
|
||||
paul 3259 1155 0 13:19 ? 00:00:00 /usr/libexec/gvfs-gphoto2-volume-monitor
|
||||
paul 3265 1155 0 13:20 ? 00:00:00 /usr/libexec/gvfs-goa-volume-monitor
|
||||
paul 3271 1155 0 13:20 ? 00:00:00 /usr/libexec/goa-daemon
|
||||
paul 3280 1155 0 13:20 ? 00:00:00 /usr/libexec/goa-identity-service
|
||||
paul 3287 1155 0 13:20 ? 00:00:00 /usr/libexec/gvfs-afc-volume-monitor
|
||||
paul 3303 3012 0 13:20 ? 00:00:02 /usr/libexec/ibus-engine-simple
|
||||
paul 3372 1155 0 13:20 ? 00:00:00 /usr/libexec/xdg-desktop-portal-gtk
|
||||
paul 3441 1155 0 13:20 ? 00:00:00 /usr/libexec/gvfsd-metadata
|
||||
paul 3453 1155 0 13:20 ? 00:00:00 /usr/libexec/evolution-calendar-factory
|
||||
paul 3495 1155 0 13:20 ? 00:00:00 /usr/libexec/evolution-addressbook-factory
|
||||
paul 4798 1155 0 13:26 ? 00:00:09 /usr/libexec/gnome-terminal-server
|
||||
paul 4810 4798 0 13:26 pts/0 00:00:00 bash
|
||||
paul 8614 1155 0 13:29 ? 00:00:01 /usr/bin/speech-dispatcher -s -t 0
|
||||
paul 8656 8614 0 13:29 ? 00:00:00 [sd_espeak-ng-mb] <defunct>
|
||||
paul 8709 8614 0 13:29 ? 00:00:00 /usr/lib/speech-dispatcher-modules/sd_espeak-ng /etc/speech-dispatcher/modules/espeak-ng.conf
|
||||
paul 8785 8614 0 13:29 ? 00:00:00 /usr/lib/speech-dispatcher-modules/sd_dummy /etc/speech-dispatcher/modules/dummy.conf
|
||||
paul 8799 8614 0 13:29 ? 00:00:00 /usr/lib/speech-dispatcher-modules/sd_espeak-ng /etc/speech-dispatcher/modules/
|
||||
paul 10028 1155 0 13:31 ? 00:00:00 adb -L tcp:5037 fork-server server --reply-fd 4
|
||||
paul 69578 2814 0 13:53 ? 00:00:00 /usr/libexec/gvfsd-http --spawner :1.22 /org/gtk/gvfs/exec_spaw/0
|
||||
paul 108341 1155 3 14:06 ? 00:00:48 /home/paul/.nvm/versions/node/v22.23.0/bin/node /home/paul/.nvm/versions/node/v22.23.0/lib/node_modules/acpx/dist/cli.js __queue-owner
|
||||
paul 108416 108341 0 14:06 ? 00:00:00 openclaw
|
||||
paul 108458 108416 2 14:06 ? 00:00:37 openclaw-acp
|
||||
paul 143553 1155 0 14:19 ? 00:00:05 /home/paul/Workspace/yavsc/src/PostIt.Tests/bin/Debug/net10.0/PostIt.Tests @@ /tmp/tmpI2JxLw.tmp
|
||||
paul 149205 1155 0 14:21 ? 00:00:05 /home/paul/Workspace/yavsc/src/PostIt.Tests/bin/Debug/net10.0/PostIt.Tests @@ /tmp/tmpitRyQG.tmp
|
||||
paul 151724 1155 0 14:22 ? 00:00:04 /home/paul/Workspace/yavsc/src/PostIt.Tests/bin/Debug/net10.0/PostIt.Tests @@ /tmp/tmpJEsOZV.tmp
|
||||
paul 157447 1155 1 14:24 ? 00:00:05 /home/paul/Workspace/yavsc/src/PostIt.Tests/bin/Debug/net10.0/PostIt.Tests @@ /tmp/tmpyM92DV.tmp
|
||||
paul 165231 1155 0 14:26 ? 00:00:01 /home/paul/Workspace/yavsc/src/PostIt.Tests/bin/Debug/net10.0/PostIt.Tests @@ /tmp/tmp5CKC19.tmp
|
||||
paul 168472 1155 4 14:27 ? 00:00:09 /home/paul/Workspace/yavsc/src/PostIt.Tests/bin/Debug/net10.0/PostIt.Tests @@ /tmp/tmpuRJsnQ.tmp
|
||||
paul 172147 1155 4 14:29 pts/0 00:00:05 /home/paul/Workspace/yavsc/src/PostIt.Tests/bin/Debug/net10.0/PostIt.Tests @@ /tmp/tmpxT8nje.tmp
|
||||
paul 172435 4810 99 14:31 pts/0 00:00:00 ps -fu paul
|
||||
Loading…
Add table
Add a link
Reference in a new issue