diff --git a/src/scripts/device/state-routes.lua b/src/scripts/device/state-routes.lua index 3349b24a..b889524b 100644 --- a/src/scripts/device/state-routes.lua +++ b/src/scripts/device/state-routes.lua @@ -159,129 +159,125 @@ store_or_restore_routes_hook = AsyncEventHook { }, steps = { start = { - next = "evaluate", + next = "none", execute = function (event, transition) + local source = event:get_source () + local device = event:get_subject () + -- Make sure the routes are always updated before evaluating them. -- https://gitlab.freedesktop.org/pipewire/wireplumber/-/issues/762 - local device = event:get_subject () - device:enum_params ("EnumRoute", function (_, e) + device:enum_params ("EnumRoute", function (enum_route_it, e) + local selected_routes = {} + local push_select_routes = false + + -- check for error if e then transition:return_error ("failed to enum routes: " .. tostring (e)); - else + return + end + + -- Make sure the device is still valid + if (device:get_active_features() & Feature.Proxy.BOUND) == 0 then transition:advance () - end - end) - end - }, - evaluate = { - next = "none", - execute = function (event, transition) - local device = event:get_subject () - local source = event:get_source () - local selected_routes = {} - local push_select_routes = false - - -- Make sure the device is still valid - if (device:get_active_features() & Feature.Proxy.BOUND) == 0 then - transition:advance () - return - end - - local dev_info = devinfo:get_device_info (device) - if not dev_info then - transition:advance () - return - end - - local new_route_infos = {} - - -- look at all the routes and update/reset cached information - for p in device:iterate_params ("EnumRoute") do - -- parse pod - local route = cutils.parseParam (p, "EnumRoute") - if not route then - goto skip_enum_route + return end - -- find cached route information - local route_info = devinfo.find_route_info (dev_info, route, true) - if not route_info then - goto skip_enum_route + local dev_info = devinfo:get_device_info (device) + if not dev_info then + transition:advance () + return end - -- update properties - route_info.prev_active = route_info.active - route_info.active = false - route_info.save = false + local new_route_infos = {} - -- store - new_route_infos [route.index] = route_info + -- look at all the routes and update/reset cached information + for p in enum_route_it:iterate() do + -- parse pod + local route = cutils.parseParam (p, "EnumRoute") + if not route then + goto skip_enum_route + end - ::skip_enum_route:: - end + -- find cached route information + local route_info = devinfo.find_route_info (dev_info, route, true) + if not route_info then + goto skip_enum_route + end - -- update route_infos with new prev_active, active and save changes - dev_info.route_infos = new_route_infos - new_route_infos = nil + -- update properties + route_info.prev_active = route_info.active + route_info.active = false + route_info.save = false - -- check for changes in the active routes - for p in device:iterate_params ("Route") do - local route = cutils.parseParam (p, "Route") - if not route then - goto skip_route + -- store + new_route_infos [route.index] = route_info + + ::skip_enum_route:: end - -- get cached route info and at the same time - -- ensure that the route is also in EnumRoute - local route_info = devinfo.find_route_info (dev_info, route, false) - if not route_info then - goto skip_route - end + -- update route_infos with new prev_active, active and save changes + dev_info.route_infos = new_route_infos + new_route_infos = nil - -- update route_info state - route_info.active = true - route_info.save = route.save + -- check for changes in the active routes + for p in device:iterate_params ("Route") do + local route = cutils.parseParam (p, "Route") + if not route then + goto skip_route + end - if not route_info.prev_active then - -- a new route is now active, restore the volume and - -- make sure we save this as a preferred route - log:info (device, - string.format ("new active route(%s) found of device(%s)", - route.name, dev_info.name)) - route_info.prev_active = true + -- get cached route info and at the same time + -- ensure that the route is also in EnumRoute + local route_info = devinfo.find_route_info (dev_info, route, false) + if not route_info then + goto skip_route + end + + -- update route_info state route_info.active = true + route_info.save = route.save - selected_routes [tostring (route.device)] = - Json.Object { index = route_info.index }:to_string () - push_select_routes = true + if not route_info.prev_active then + -- a new route is now active, restore the volume and + -- make sure we save this as a preferred route + log:info (device, + string.format ("new active route(%s) found of device(%s)", + route.name, dev_info.name)) + route_info.prev_active = true + route_info.active = true - elseif route.available ~= "no" and route.save and route.props then - -- just save route properties - log:info (device, - string.format ("storing route(%s) props of device(%s)", - route.name, dev_info.name)) + selected_routes [tostring (route.device)] = + Json.Object { index = route_info.index }:to_string () + push_select_routes = true - saveRouteProps (dev_info, route) + elseif route.available ~= "no" and route.save and route.props then + -- just save route properties + log:info (device, + string.format ("storing route(%s) props of device(%s)", + route.name, dev_info.name)) + + saveRouteProps (dev_info, route) + end + + ::skip_route:: end - ::skip_route:: - end + -- save selected routes for the active profile + for p in device:iterate_params ("Profile") do + local profile = cutils.parseParam (p, "Profile") + saveProfileRoutes (dev_info, profile.name) + end - -- save selected routes for the active profile - for p in device:iterate_params ("Profile") do - local profile = cutils.parseParam (p, "Profile") - saveProfileRoutes (dev_info, profile.name) - end + -- push a select-routes event to re-apply the routes with new properties + if push_select_routes then + local e = source:call ("create-event", "select-routes", device, nil) + e:set_data ("selected-routes", selected_routes) + EventDispatcher.push_event (e) + end - -- push a select-routes event to re-apply the routes with new properties - if push_select_routes then - local e = source:call ("create-event", "select-routes", device, nil) - e:set_data ("selected-routes", selected_routes) - EventDispatcher.push_event (e) - end - - transition:advance () + transition:advance () + end) end } }