summaryrefslogtreecommitdiff
path: root/src/services/workspaces/sway-workspace-service.c
diff options
context:
space:
mode:
authorHannes Schulze <contact@haschu.me>2026-04-26 13:23:40 +0200
committerHannes Schulze <contact@haschu.me>2026-04-26 13:23:40 +0200
commiteb127fbd2787a8b15ab5b81abc7bf495a0508399 (patch)
tree49724159fa42a878a026283a8a95f3a5332a46e7 /src/services/workspaces/sway-workspace-service.c
parentc783a6ca1cb13126f2ff06a92296994b446c8fed (diff)
handle sway eventsHEADmain
Diffstat (limited to 'src/services/workspaces/sway-workspace-service.c')
-rw-r--r--src/services/workspaces/sway-workspace-service.c295
1 files changed, 208 insertions, 87 deletions
diff --git a/src/services/workspaces/sway-workspace-service.c b/src/services/workspaces/sway-workspace-service.c
index e031db8..73745e3 100644
--- a/src/services/workspaces/sway-workspace-service.c
+++ b/src/services/workspaces/sway-workspace-service.c
@@ -103,58 +103,64 @@ enum
N_PROPS,
};
-static void foobar_sway_workspace_service_class_init ( FoobarSwayWorkspaceServiceClass* klass );
-static void foobar_sway_workspace_service_interface_init ( FoobarWorkspaceServiceInterface* iface );
-static void foobar_sway_workspace_service_init ( FoobarSwayWorkspaceService* self );
-static void foobar_sway_workspace_service_get_property ( GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec );
-static void foobar_sway_workspace_service_dispose ( GObject* object );
-static void foobar_sway_workspace_service_finalize ( GObject* object );
-static GListModel* foobar_sway_workspace_service_get_workspaces ( FoobarWorkspaceService* service );
-static gboolean foobar_sway_workspace_service_is_available ( FoobarWorkspaceService* service );
-static void foobar_sway_workspace_service_handle_workspace_init ( FoobarSwayWorkspaceService* service,
- JsonObject* current,
- JsonObject* old );
-static void foobar_sway_workspace_service_handle_workspace_empty ( FoobarSwayWorkspaceService* service,
- JsonObject* current,
- JsonObject* old );
-static void foobar_sway_workspace_service_handle_workspace_focus ( FoobarSwayWorkspaceService* service,
- JsonObject* current,
- JsonObject* old );
-static void foobar_sway_workspace_service_handle_workspace_move ( FoobarSwayWorkspaceService* service,
- JsonObject* current,
- JsonObject* old );
-static void foobar_sway_workspace_service_handle_workspace_rename( FoobarSwayWorkspaceService* service,
- JsonObject* current,
- JsonObject* old );
-static void foobar_sway_workspace_service_handle_workspace_urgent( FoobarSwayWorkspaceService* service,
- JsonObject* current,
- JsonObject* old );
-static void foobar_sway_workspace_service_handle_workspace_reload( FoobarSwayWorkspaceService* service,
- JsonObject* current,
- JsonObject* old );
-static gpointer foobar_sway_workspace_service_event_thread_func ( gpointer userdata );
-static void foobar_sway_workspace_service_initialize ( FoobarSwayWorkspaceService* self );
-static gboolean foobar_sway_workspace_service_handle_event ( EventData* data );
-static JsonNode* foobar_sway_workspace_service_send_request ( FoobarSwayWorkspaceService* self,
- guint type,
- gchar const* payload,
- GError** error );
-static gboolean foobar_sway_workspace_service_write ( GSocket* socket,
- guint32 type,
- gchar const* payload,
- GCancellable* cancellable,
- GError** out_error );
-static JsonNode* foobar_sway_workspace_service_read ( GSocket* socket,
- guint32* out_type,
- GCancellable* cancellable,
- GError** out_error );
-static gchar* foobar_sway_workspace_service_get_socket_path ( void );
-static gint foobar_sway_workspace_service_sort_func ( gconstpointer item_a,
- gconstpointer item_b,
- gpointer userdata );
+static void foobar_sway_workspace_service_class_init ( FoobarSwayWorkspaceServiceClass* klass );
+static void foobar_sway_workspace_service_interface_init ( FoobarWorkspaceServiceInterface* iface );
+static void foobar_sway_workspace_service_init ( FoobarSwayWorkspaceService* self );
+static void foobar_sway_workspace_service_get_property ( GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec );
+static void foobar_sway_workspace_service_dispose ( GObject* object );
+static void foobar_sway_workspace_service_finalize ( GObject* object );
+static GListModel* foobar_sway_workspace_service_get_workspaces ( FoobarWorkspaceService* service );
+static gboolean foobar_sway_workspace_service_is_available ( FoobarWorkspaceService* service );
+static void foobar_sway_workspace_service_handle_workspace_init ( FoobarSwayWorkspaceService* service,
+ JsonObject* current,
+ JsonObject* old );
+static void foobar_sway_workspace_service_handle_workspace_empty ( FoobarSwayWorkspaceService* service,
+ JsonObject* current,
+ JsonObject* old );
+static void foobar_sway_workspace_service_handle_workspace_focus ( FoobarSwayWorkspaceService* service,
+ JsonObject* current,
+ JsonObject* old );
+static void foobar_sway_workspace_service_handle_workspace_move ( FoobarSwayWorkspaceService* service,
+ JsonObject* current,
+ JsonObject* old );
+static void foobar_sway_workspace_service_handle_workspace_rename( FoobarSwayWorkspaceService* service,
+ JsonObject* current,
+ JsonObject* old );
+static void foobar_sway_workspace_service_handle_workspace_urgent( FoobarSwayWorkspaceService* service,
+ JsonObject* current,
+ JsonObject* old );
+static void foobar_sway_workspace_service_handle_workspace_reload( FoobarSwayWorkspaceService* service,
+ JsonObject* current,
+ JsonObject* old );
+static gpointer foobar_sway_workspace_service_event_thread_func ( gpointer userdata );
+static void foobar_sway_workspace_service_initialize ( FoobarSwayWorkspaceService* self );
+static void foobar_sway_workspace_service_add_workspace ( FoobarSwayWorkspaceService* self,
+ GListStore* workspaces,
+ JsonObject* workspace_object );
+static FoobarSwayWorkspace* foobar_sway_workspace_service_find_workspace ( GListModel* workspaces,
+ JsonObject* workspace_object,
+ guint* out_index );
+static gboolean foobar_sway_workspace_service_handle_event ( EventData* data );
+static JsonNode* foobar_sway_workspace_service_send_request ( FoobarSwayWorkspaceService* self,
+ guint type,
+ gchar const* payload,
+ GError** error );
+static gboolean foobar_sway_workspace_service_write ( GSocket* socket,
+ guint32 type,
+ gchar const* payload,
+ GCancellable* cancellable,
+ GError** out_error );
+static JsonNode* foobar_sway_workspace_service_read ( GSocket* socket,
+ guint32* out_type,
+ GCancellable* cancellable,
+ GError** out_error );
+static gchar* foobar_sway_workspace_service_get_socket_path ( void );
+static gint foobar_sway_workspace_service_sort_func ( gconstpointer item_a,
+ gconstpointer item_b,
+ gpointer userdata );
G_DEFINE_TYPE_WITH_CODE(
FoobarSwayWorkspaceService, foobar_sway_workspace_service, G_TYPE_OBJECT,
@@ -626,59 +632,137 @@ FoobarWorkspaceService* foobar_sway_workspace_service_new( void )
// ---------------------------------------------------------------------------------------------------------------------
void foobar_sway_workspace_service_handle_workspace_init(
- FoobarSwayWorkspaceService* service,
+ FoobarSwayWorkspaceService* self,
JsonObject* current,
JsonObject* old )
{
- g_print( "[init] %p %p\n", current, old );
+ (void)old;
+
+ foobar_sway_workspace_service_add_workspace( self, self->workspaces, current );
}
void foobar_sway_workspace_service_handle_workspace_empty(
- FoobarSwayWorkspaceService* service,
+ FoobarSwayWorkspaceService* self,
JsonObject* current,
JsonObject* old )
{
- g_print( "[empty] %p %p\n", current, old );
+ (void)old;
+
+ guint index;
+ FoobarSwayWorkspace* workspace =
+ foobar_sway_workspace_service_find_workspace( G_LIST_MODEL( self->workspaces ), current, &index );
+ if ( workspace )
+ {
+ workspace->service = NULL;
+ g_list_store_remove( self->workspaces, index );
+ }
}
void foobar_sway_workspace_service_handle_workspace_focus(
- FoobarSwayWorkspaceService* service,
+ FoobarSwayWorkspaceService* self,
JsonObject* current,
JsonObject* old )
{
- g_print( "[focus] %p %p\n", current, old );
+ FoobarSwayWorkspace* old_workspace =
+ foobar_sway_workspace_service_find_workspace( G_LIST_MODEL( self->workspaces ), old, NULL );
+ FoobarSwayWorkspace* new_workspace =
+ foobar_sway_workspace_service_find_workspace( G_LIST_MODEL( self->workspaces ), current, NULL );
+
+ if ( old_workspace )
+ {
+ FoobarWorkspaceFlags flags = foobar_workspace_get_flags( FOOBAR_WORKSPACE( old_workspace ) );
+ flags &= ~FOOBAR_WORKSPACE_FLAGS_ACTIVE;
+ gchar const* old_output = json_object_get_string_member( old, "output" );
+ gchar const* new_output = json_object_get_string_member( current, "output" );
+ if ( g_strcmp0( old_output, new_output ) == 0 )
+ {
+ // Intra-output switch; the old workspace is no longer visible.
+ flags &= ~FOOBAR_WORKSPACE_FLAGS_VISIBLE;
+ }
+ foobar_sway_workspace_set_flags( old_workspace, flags );
+ }
+
+ if ( new_workspace )
+ {
+ FoobarWorkspaceFlags flags = foobar_workspace_get_flags( FOOBAR_WORKSPACE( new_workspace ) );
+ flags |= FOOBAR_WORKSPACE_FLAGS_ACTIVE;
+ flags |= FOOBAR_WORKSPACE_FLAGS_VISIBLE;
+ foobar_sway_workspace_set_flags( new_workspace, flags );
+ }
}
void foobar_sway_workspace_service_handle_workspace_move(
- FoobarSwayWorkspaceService* service,
+ FoobarSwayWorkspaceService* self,
JsonObject* current,
JsonObject* old )
{
- g_print( "[move] %p %p\n", current, old );
+ (void)old;
+
+ FoobarSwayWorkspace* workspace =
+ foobar_sway_workspace_service_find_workspace( G_LIST_MODEL( self->workspaces ), current, NULL );
+
+ if ( workspace )
+ {
+ gchar const* new_output = json_object_get_string_member( current, "output" );
+ foobar_sway_workspace_set_monitor( workspace, new_output );
+ g_signal_emit_by_name( self, "monitor-configuration-changed" );
+ }
}
void foobar_sway_workspace_service_handle_workspace_rename(
- FoobarSwayWorkspaceService* service,
+ FoobarSwayWorkspaceService* self,
JsonObject* current,
JsonObject* old )
{
- g_print( "[rename] %p %p\n", current, old );
+ (void)old;
+
+ FoobarSwayWorkspace* workspace =
+ foobar_sway_workspace_service_find_workspace( G_LIST_MODEL( self->workspaces ), current, NULL );
+
+ if ( workspace )
+ {
+ gchar const* new_name = json_object_get_string_member( current, "name" );
+ foobar_sway_workspace_set_name( workspace, new_name );
+ gtk_sorter_changed(
+ gtk_sort_list_model_get_sorter( self->sorted_workspaces ),
+ GTK_SORTER_CHANGE_DIFFERENT );
+ }
}
void foobar_sway_workspace_service_handle_workspace_urgent(
- FoobarSwayWorkspaceService* service,
+ FoobarSwayWorkspaceService* self,
JsonObject* current,
JsonObject* old )
{
- g_print( "[urgent] %p %p\n", current, old );
+ (void)old;
+
+ FoobarSwayWorkspace* workspace =
+ foobar_sway_workspace_service_find_workspace( G_LIST_MODEL( self->workspaces ), current, NULL );
+
+ if ( workspace )
+ {
+ FoobarWorkspaceFlags flags = foobar_workspace_get_flags( FOOBAR_WORKSPACE( workspace ) );
+ if ( json_object_get_boolean_member( current, "urgent" ) )
+ {
+ flags |= FOOBAR_WORKSPACE_FLAGS_URGENT;
+ }
+ else
+ {
+ flags &= ~FOOBAR_WORKSPACE_FLAGS_URGENT;
+ }
+ foobar_sway_workspace_set_flags( workspace, flags );
+ }
}
void foobar_sway_workspace_service_handle_workspace_reload(
- FoobarSwayWorkspaceService* service,
+ FoobarSwayWorkspaceService* self,
JsonObject* current,
JsonObject* old )
{
- g_print( "[reload] %p %p\n", current, old );
+ (void)current;
+ (void)old;
+
+ foobar_sway_workspace_service_initialize( self );
}
// ---------------------------------------------------------------------------------------------------------------------
@@ -794,27 +878,7 @@ void foobar_sway_workspace_service_initialize( FoobarSwayWorkspaceService* self
for ( guint i = 0; i < json_array_get_length( workspaces_array ); ++i )
{
JsonObject* workspace_object = json_array_get_object_element( workspaces_array, i );
- gchar const* name = json_object_get_string_member( workspace_object, "name" );
- gchar const* output = json_object_get_string_member( workspace_object, "output" );
- gint64 id = json_object_get_int_member( workspace_object, "id" );
- gint64 num = json_object_get_int_member( workspace_object, "num" );
- gboolean visible = json_object_get_boolean_member( workspace_object, "visible" );
- gboolean focused = json_object_get_boolean_member( workspace_object, "focused" );
- gboolean urgent = json_object_get_boolean_member( workspace_object, "urgent" );
-
- FoobarWorkspaceFlags flags = FOOBAR_WORKSPACE_FLAGS_NONE;
- flags = visible ? flags | FOOBAR_WORKSPACE_FLAGS_VISIBLE : flags;
- flags = focused ? flags | FOOBAR_WORKSPACE_FLAGS_ACTIVE : flags;
- flags = urgent ? flags | FOOBAR_WORKSPACE_FLAGS_URGENT : flags;
-
- g_autoptr(FoobarSwayWorkspace) workspace = foobar_sway_workspace_new( self );
- foobar_sway_workspace_set_id( workspace, id );
- foobar_sway_workspace_set_num( workspace, num );
- foobar_sway_workspace_set_name( workspace, name );
- foobar_sway_workspace_set_monitor( workspace, output );
- foobar_sway_workspace_set_flags( workspace, flags );
-
- g_list_store_append( workspaces, workspace );
+ foobar_sway_workspace_service_add_workspace( self, workspaces, workspace_object );
}
}
@@ -825,6 +889,63 @@ void foobar_sway_workspace_service_initialize( FoobarSwayWorkspaceService* self
}
}
+//
+// Add a newly initialized workspace from a JSON object.
+//
+void foobar_sway_workspace_service_add_workspace(
+ FoobarSwayWorkspaceService* self,
+ GListStore* workspaces,
+ JsonObject* workspace_object )
+{
+ gchar const* name = json_object_get_string_member( workspace_object, "name" );
+ gchar const* output = json_object_get_string_member( workspace_object, "output" );
+ gint64 id = json_object_get_int_member( workspace_object, "id" );
+ gint64 num = json_object_get_int_member( workspace_object, "num" );
+ gboolean visible = json_object_get_boolean_member_with_default( workspace_object, "visible", FALSE );
+ gboolean focused = json_object_get_boolean_member( workspace_object, "focused" );
+ gboolean urgent = json_object_get_boolean_member( workspace_object, "urgent" );
+
+ FoobarWorkspaceFlags flags = FOOBAR_WORKSPACE_FLAGS_NONE;
+ flags = visible ? flags | FOOBAR_WORKSPACE_FLAGS_VISIBLE : flags;
+ flags = focused ? flags | FOOBAR_WORKSPACE_FLAGS_ACTIVE : flags;
+ flags = urgent ? flags | FOOBAR_WORKSPACE_FLAGS_URGENT : flags;
+
+ g_autoptr(FoobarSwayWorkspace) workspace = foobar_sway_workspace_new( self );
+ foobar_sway_workspace_set_id( workspace, id );
+ foobar_sway_workspace_set_num( workspace, num );
+ foobar_sway_workspace_set_name( workspace, name );
+ foobar_sway_workspace_set_monitor( workspace, output );
+ foobar_sway_workspace_set_flags( workspace, flags );
+
+ g_list_store_append( workspaces, workspace );
+}
+
+//
+// Find an existing workspace object by its ID from the given JSON object.
+//
+FoobarSwayWorkspace* foobar_sway_workspace_service_find_workspace(
+ GListModel* workspaces,
+ JsonObject* workspace_object,
+ guint* out_index )
+{
+ gint64 id = json_object_get_int_member( workspace_object, "id" );
+
+ for ( guint i = 0; i < g_list_model_get_n_items( workspaces ); ++i )
+ {
+ FoobarSwayWorkspace* workspace = g_list_model_get_item( workspaces, i );
+ if ( foobar_workspace_get_id( FOOBAR_WORKSPACE( workspace ) ) == id )
+ {
+ if ( out_index ) { *out_index = i; }
+ return workspace;
+ }
+ }
+
+ return NULL;
+}
+
+//
+// GSourceFunc handling "workspace" events, dispatched by the event thread.
+//
gboolean foobar_sway_workspace_service_handle_event( EventData* data )
{
JsonObject* event_object = json_node_get_object( data->payload );