Skip to content

Commit

Permalink
fix: desktopCapturer and screen display ids should match (#42890)
Browse files Browse the repository at this point in the history
* fix: `desktopCapturer` and `screen` display IDs should match

Co-authored-by: clavin <clavin@electronjs.org>

* simplify wide-to-utf8 conversion

Co-authored-by: clavin <clavin@electronjs.org>

* remove unnecessary include

Co-authored-by: clavin <clavin@electronjs.org>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: clavin <clavin@electronjs.org>
  • Loading branch information
trop[bot] and clavin authored Jul 14, 2024
1 parent 05abc2b commit 5c2a8b9
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 16 deletions.
33 changes: 21 additions & 12 deletions shell/browser/api/electron_api_desktop_capturer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -399,28 +399,37 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
if (using_directx_capturer_) {
std::vector<std::string> device_names;
// Crucially, this list of device names will be in the same order as
// |media_list_sources|.
// |screen_sources|.
if (!webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(
&device_names)) {
HandleFailure();
return;
}
DCHECK_EQ(device_names.size(), screen_sources.size());

std::vector<HMONITOR> monitors;
EnumDisplayMonitors(nullptr, nullptr, EnumDisplayMonitorsCallback,
reinterpret_cast<LPARAM>(&monitors));

std::vector<std::pair<std::string, MONITORINFOEX>> pairs;
for (const auto& device_name : device_names) {
std::wstring wide_device_name;
base::UTF8ToWide(device_name.c_str(), device_name.size(),
&wide_device_name);
for (const auto monitor : monitors) {
MONITORINFOEX monitorInfo{{sizeof(MONITORINFOEX)}};
if (GetMonitorInfo(monitor, &monitorInfo)) {
if (wide_device_name == monitorInfo.szDevice)
pairs.push_back(std::make_pair(device_name, monitorInfo));
}
base::flat_map<std::string, int64_t> device_name_to_id;
device_name_to_id.reserve(monitors.size());
for (auto* monitor : monitors) {
MONITORINFOEX monitorInfo{{sizeof(MONITORINFOEX)}};
if (!GetMonitorInfo(monitor, &monitorInfo)) {
continue;
}

device_name_to_id[base::WideToUTF8(monitorInfo.szDevice)] =
display::win::internal::DisplayInfo::DisplayIdFromMonitorInfo(
monitorInfo);
}

int device_name_index = 0;
for (auto& source : screen_sources) {
const auto& device_name = device_names[device_name_index++];
if (auto id_iter = device_name_to_id.find(device_name);
id_iter != device_name_to_id.end()) {
source.display_id = base::NumberToString(id_iter->second);
}
}
}
Expand Down
7 changes: 3 additions & 4 deletions spec/api-screen-spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { expect } from 'chai';
import { Display, screen, desktopCapturer } from 'electron/main';
import { ifit } from './lib/spec-helpers';

describe('screen module', () => {
describe('methods reassignment', () => {
Expand All @@ -24,14 +23,14 @@ describe('screen module', () => {
}
});

// desktopCapturer.getSources does not work as expected in Windows CI.
ifit(process.platform !== 'win32')('returns displays with IDs matching desktopCapturer source display IDs', async () => {
it('returns displays with IDs matching desktopCapturer source display IDs', async () => {
const displayIds = screen.getAllDisplays().map(d => `${d.id}`);

const sources = await desktopCapturer.getSources({ types: ['screen'] });
const sourceIds = sources.map(s => s.display_id);

expect(displayIds).to.have.members(sourceIds);
expect(displayIds).to.have.length(sources.length);
expect(displayIds).to.have.same.members(sourceIds);
});
});

Expand Down

0 comments on commit 5c2a8b9

Please sign in to comment.