Skip to content

w32_common: Implement --screen-name #16098

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

BreadFish64
Copy link

@BreadFish64 BreadFish64 commented Mar 23, 2025

Previously the --screen-name and --fs-screen-name options did nothing on Windows.

It now attempts to convert a friendly monitor name to the GDI device name using the DisplayConfig API first. The friendly name is the shown in Windows settings like "Dell AW3423DW". Otherwise, assume it's already a GDI device name like "\.\DISPLAY1".

Edit: Added commit

w32_common: add display-names/friendly property

The friendly subkey return the same set of displays as display-names
but it attempts to convert the names to the human-friendly name that
DisplayConfig obtains from the EDID.

@kasper93
Copy link
Member

Nice. Could you also extend mp_property_display_names with the friendly name? It was requested feature #13743 to use in scripts instead of device name.

Copy link

github-actions bot commented Mar 23, 2025

Download the artifacts for this pull request:

Windows
macOS

@BreadFish64
Copy link
Author

@kasper93 Do you want to just change it from the GDI names to the friendly names completely? That seems easy enough.

@kasper93
Copy link
Member

@kasper93 Do you want to just change it from the GDI names to the friendly names completely? That seems easy enough.

Not sure, there may be users who wants GDI names. Maybe we do M_PROPERTY_KEY_ACTION with friendly key? So display-names return GDI names as it do now and new display-names/friendly would return friendly device name?

@BreadFish64
Copy link
Author

Sounds reasonable. I'll poke at it tomorrow.

@BreadFish64
Copy link
Author

Added the friendly subkey.
You can try it by dragging the window around with this script

function func(_, value)
    local display_names = mp.get_property("display-names")
    if display_names then
        print("Display names:\n" .. display_names .. "\n")
    end
    if value then
        print("Friendly display names:\n" .. value .. "\n")
    end
end

mp.observe_property("display-names/friendly", "string", func)

end:
talloc_free(ctx);
return monitor_friendly_device_name;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you move common part to separate function, just to avoid duplication, even if it's not that much.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, yeah it seems like there should be a way to combine these, but since they use two different query structs, DISPLAYCONFIG_SOURCE_DEVICE_NAME and DISPLAYCONFIG_TARGET_DEVICE_NAME, there's not much overlap.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could move lines 230-248 and 190-204 to separate functions and call in common function based on flag which one name you want to get.

@kasper93 kasper93 added this to the Release v0.41.0 milestone Mar 23, 2025
Previously the --screen-name and --fs-screen-name options did nothing
on Windows.

It now attempts to convert a friendly monitor name
to the GDI device name using the DisplayConfig API first.
The `friendly` subkey return the same set of displays as `display-names`
but it attempts to convert the names to the human-friendly name that
DisplayConfig obtains from the EDID.
end:
talloc_free(ctx);
return monitor_friendly_device_name;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could move lines 230-248 and 190-204 to separate functions and call in common function based on flag which one name you want to get.

static BOOL CALLBACK get_monitor_by_name_proc(HMONITOR mon, HDC dc, LPRECT r,
LPARAM p)
{
struct get_monitor_by_name_data *const data = (struct get_monitor_by_name_data*)p;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
struct get_monitor_by_name_data *const data = (struct get_monitor_by_name_data*)p;
struct get_monitor_by_name_data *const data = (struct get_monitor_by_name_data *)p;

{
struct get_monitor_by_name_data *const data = (struct get_monitor_by_name_data*)p;

MONITORINFOEXW mi = { .cbSize = sizeof mi };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
MONITORINFOEXW mi = { .cbSize = sizeof mi };
MONITORINFOEXW mi = { .cbSize = sizeof(mi) };

struct get_monitor_by_name_data *const data = (struct get_monitor_by_name_data*)p;

MONITORINFOEXW mi = { .cbSize = sizeof mi };
if (GetMonitorInfoW(mon, (MONITORINFO*)&mi)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (GetMonitorInfoW(mon, (MONITORINFO*)&mi)) {
if (GetMonitorInfoW(mon, (LPMONITORINFO)&mi)) {

return TRUE;
}

static HMONITOR get_monitor_by_name(const wchar_t* name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
static HMONITOR get_monitor_by_name(const wchar_t* name)
static HMONITOR get_monitor_by_name(const wchar_t *name)

static void disp_names_append(HMONITOR mon, struct disp_names_data *data)
{
MONITORINFOEXW mi = { .cbSize = sizeof mi };
if (GetMonitorInfoW(mon, (MONITORINFO*)&mi)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same remarks as before.

Comment on lines +2933 to +2936
``display-names/friendly``
These are the human-friendly names obtained from the monitor EDID
(Dell AW3223DW, LC34G55T, etc.). These follow the same order as
``display-names`` (Windows only)
Copy link
Contributor

@CogentRedTester CogentRedTester Mar 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might it be worth making the property available on all systems, but merely act as a duplicate of display-names for non-windows systems? That way scripts, keybinds, and auto-profiles don't need to worry about the platform when grabbing useful display names, they could just grab display-names/friendly and have it work on all systems.

Edit: or would this impact adding friendlier names for other platforms later?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On linux, the display names are already friendly (i.e. like DP-1). I think macOS is similar. As opposed to "friendly" names, this seems to be more like the model name of the display. It's certainly possible to add it to other platforms.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can handle this new VOCTRL everywhere, for now with the same impl, and extended if needed.

Copy link
Member

@Akemi Akemi Mar 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just as info, on macOS it's something like DELL U2723QE (12343224), name + serial number.
f7a32b5

@Akemi
Copy link
Member

Akemi commented Mar 26, 2025

just wanted to mention, when i changed the display names on macOS in f7a32b5 i had the problem that those 'friendly' names are not deterministic, see the commit. eg same model displays have the same name or were numerated 'randomly'. that's the reason why i added the serial number to those names, to make them unique.

you might have the same problem here.

@kasper93
Copy link
Member

just wanted to mention, when i changed the display names on macOS in f7a32b5 i had the problem that those 'friendly' names are not deterministic, see the commit. eg same model displays have the same name or were numerated 'randomly'. that's the reason why i added the serial number to those names, to make them unique.

you might have the same problem here.

Yes, exactly, that's why I suggested to keep GDI path that and friendly name too.

@Dudemanguy
Copy link
Member

Having multiple names exposed for the same display makes sense to me. How do we want to separate it? The existing display-names could be the names of the connectors (like HDMI-1, etc.) and we could have a display-names/model for the model name? I don't know if that makes sense on other platforms but at least on linux that would be the idea. --screen-name and similar options could accept either one.

@kasper93
Copy link
Member

So display-names/friendly would get renamed to display-names/model. Also following the concern from @Akemi, we can append (N) to duplicated names. Or unify and get some serial number.

Though, I once was thinking about it long time ago and wanted to do model name (GDI path) but this gets verbose and long. So for /model short index would be preferable. And for display-names it would be always unambiguous path returned from API.

And I agree, this is good opportunity to unify it little bit between macOS, Wayland and Windows.

@dyphire
Copy link
Contributor

dyphire commented Mar 26, 2025

So display-names/friendly would get renamed to display-names/model. Also following the concern from @Akemi, we can append (N) to duplicated names. Or unify and get some serial number.

I think it would be better to append the serial number to the monitor name, while maintaining consistency with the behavior on macos.

Though, I once was thinking about it long time ago and wanted to do model name (GDI path) but this gets verbose and long. So for /model short index would be preferable. And for display-names it would be always unambiguous path returned from API.

I don't think it's a good idea to append the GDI path to the monitor name. As mentioned in #13743, the GDI path assigned to each monitor by the Windows system is not fixed, it changes for various reasons. This makes the property will remain unusable for persistent configuration. Glad to know it's an abandoned idea.

@Akemi
Copy link
Member

Akemi commented Mar 26, 2025

So display-names/friendly would get renamed to display-names/model. Also following the concern from @Akemi, we can append (N) to duplicated names. Or unify and get some serial number.

for duplicate name also keep runtime in mind, eg you plug in the first display it would be ["Display"], plugging in a second one of the same model it would be ["Display (1)", "Display (2)"]. the first display would change names in that case. names would be unique but not deterministic.

@kasper93
Copy link
Member

So display-names/friendly would get renamed to display-names/model. Also following the concern from @Akemi, we can append (N) to duplicated names. Or unify and get some serial number.

for duplicate name also keep runtime in mind, eg you plug in the first display it would be ["Display"], plugging in a second one of the same model it would be ["Display (1)", "Display (2)"]. the first display would change names in that case. names would be unique but not deterministic.

It would be ["Display", "Display (1)"], but if you change order in which system sees them, they could swap. Which is similar issue that is with GDI that can change when reinstalling driver or changing configuration.

If we want to have physical label, the serial number is an option, though it's not that friendly, because you wouldn't use it anywhere else except mpv. Connector number would be good too, but not sure if either of this information is easy to extract in Windows.

@Akemi
Copy link
Member

Akemi commented Mar 26, 2025

then you would also have the case that both display are plugged in already. would it be ["Display", "Display (1)"] or ["Display (1)", "Display (2)"]. anyway, my case is that it's not deterministic. also in the case that you mentioned.

i also want to mention that serial numbers aren't safe either in following cases:

  • displays have 'null' serial numbers or any kind of fuck up, like same serial numbers etc. both cases are not unheard of. some manufactures give a whole batch of displays the same serial number, or so i have heard
  • if you plug in the same display twice (on two different ports) or more

the latter case could be valid, for example when using the display's PiP/PaP features.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants