@@ -61,20 +61,35 @@ namespace wl {
6161 return -1 ;
6262 }
6363
64+ // Populate xdg_output info (name, viewport) for every monitor up
65+ // front so we can match by stable name in addition to index.
66+ for (auto &m : interface.monitors ) {
67+ m->listen (interface.output_manager );
68+ }
69+ display.roundtrip ();
70+
6471 auto monitor = interface.monitors [0 ].get ();
6572
6673 if (!display_name.empty ()) {
67- auto streamedMonitor = util::from_view (display_name);
68-
69- if (streamedMonitor >= 0 && streamedMonitor < interface.monitors .size ()) {
70- monitor = interface.monitors [streamedMonitor].get ();
74+ // Match by xdg_output name first (stable across hotplug, e.g.
75+ // "eDP-1", "HEADLESS-2"). Fall back to numeric index for
76+ // backward compatibility with existing configs.
77+ bool matched = false ;
78+ for (auto &m : interface.monitors ) {
79+ if (m->name == display_name) {
80+ monitor = m.get ();
81+ matched = true ;
82+ break ;
83+ }
84+ }
85+ if (!matched) {
86+ auto streamedMonitor = util::from_view (display_name);
87+ if (streamedMonitor >= 0 && streamedMonitor < interface.monitors .size ()) {
88+ monitor = interface.monitors [streamedMonitor].get ();
89+ }
7190 }
7291 }
7392
74- monitor->listen (interface.output_manager );
75-
76- display.roundtrip ();
77-
7893 output = monitor->output ;
7994
8095 offset_x = monitor->viewport .offset_x ;
@@ -462,7 +477,7 @@ namespace platf {
462477
463478 BOOST_LOG (info) << " [wlgrab] Monitor " << x << " is " sv << monitor->name << " : " sv << monitor->description ;
464479
465- display_names.emplace_back (std::to_string (x));
480+ display_names.emplace_back (monitor-> name . empty () ? std::to_string (x) : monitor-> name );
466481 }
467482
468483 BOOST_LOG (info) << " [wlgrab] --------- End of Wayland monitor list ---------" sv;
0 commit comments