diff options
Diffstat (limited to 'src/services')
| -rw-r--r-- | src/services/workspaces/sway-workspace-service.c | 295 |
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 ); |
