#!/usr/bin/env perl use strict; use warnings; use Data::Dumper; unless (exists $ENV{'WAYLAND_DISPLAY'}) { die "Not running in WAYLAND"; } my $app = {}; $app->{'displays'} = {}; get_display_info($app); show_debug(Data::Dumper->Dump([$app])); my $wlr_line = get_wlr_line($app); print "${wlr_line}\n"; # ----------- # Subroutines # ----------- sub get_display_info { my ($app) = @_; open (my $RANDRH, "wlr-randr |") or die "Couldn't run wlr-randr"; my @lines = map { chomp(); $_ } <$RANDRH>; close ($RANDRH); my $state = "IDLE"; my $curr_disp = "UNDEF"; my $disp_info = {}; foreach my $ln (@lines) { if (my ($dn, $dd) = $ln =~ /^(\S+)\s+"([^"]+)"$/) { $state = "IN_DISP"; unless (exists $disp_info->{$dn}) { $disp_info->{$dn} = {}; $disp_info->{$dn}->{'name'} = $dn; $curr_disp = $dn; $disp_info->{$dn}->{'desc'} = $dd; } } if (($state eq "IN_DISP") || ($state eq "IN_MODES")) { if (my ($k,$v) = $ln =~ /\s+(\w+)\s*:\s*(.*)?$/) { if ($k eq "Modes") { $state = "IN_MODES"; $disp_info->{$curr_disp}->{'modes'} = []; } else { $disp_info->{$curr_disp}->{$k} = $v; $state = "IN_DISP" } } } if ($state eq "IN_MODES") { if (my ($mode_string) = $ln =~ /\s+(.+)$/) { # 1920x1080 px, 60.000999 Hz (preferred, current) my ($h, $v, $f, $a) = $mode_string =~ /(\d+)x(\d+)\s*px,\s*(\S+)\s*Hz\s*\((.*)\)$/; my $mode_info = {}; $mode_info->{'horizontal'} = $h; $mode_info->{'vertical'} = $v; $mode_info->{'refresh_freq'} = $f; if (defined $a) { $mode_info->{'attributes'} = [split (/\s*,\s*/, $a)]; if ($a =~ /current/) { $disp_info->{$curr_disp}->{'current_mode'} = $mode_info; } if ($a =~ /preferred/) { $disp_info->{$curr_disp}->{'preferred_mode'} = $mode_info; } } push(@{$disp_info->{$curr_disp}->{'modes'}}, $mode_info); } } # show_debug("$state: $ln"); } $app->{'displays'} = $disp_info; } # ----------- sub get_wlr_line { my ($app) = @_; my $wlr_line = "UNKNOWN"; my $num_disps = scalar(keys(%{$app->{'displays'}})); if ($num_disps == 1) { show_debug("Single display configuration"); $wlr_line = "wlr-randr --output HDMI-A-1 --off --output eDP-1 --on --pos 0,0" } elsif ($num_disps > 1) { # Determine setup (Custom) # # - Den room (DELL 27" monitor on the left of laptop display) my $matching_disps = has_display_with_name($app, "DELL U27"); if (scalar (@{$matching_disps}) == 1) { my ($h, $v) = get_display_current_dimensions($app, $matching_disps->[0]); my $disp_name = $matching_disps->[0]->{'name'}; show_debug("Multiple display configuration: Den room"); $wlr_line = "wlr-randr --output ${disp_name} --on --pos 0,0 --output eDP-1 --on --pos ${h},0"; } # # - Media room (DELL 24" monitor above laptop display) $matching_disps = has_display_with_name($app, "DELL U24"); if (scalar (@{$matching_disps}) == 1) { my ($h, $v) = get_display_current_dimensions($app, $matching_disps->[0]); my $disp_name = $matching_disps->[0]->{'name'}; show_debug("Multiple display configuration: Media room"); $wlr_line = "wlr-randr --output ${disp_name} --on --pos 0,0 --output eDP-1 --on --pos 0,${v}"; } } else { show_debug("No displays?!"); } return $wlr_line; } # ----------- sub has_display_with_name { my ($app, $name) = @_; my $found = []; foreach my $k (keys %{$app->{'displays'}}) { if ($app->{'displays'}->{$k}->{'desc'} =~ /$name/) { push(@{$found}, $app->{'displays'}->{$k}); } } return $found; } # ----------- sub get_display_current_dimensions { my ($app, $disp) = @_; return ($disp->{'current_mode'}->{'horizontal'}, $disp->{'current_mode'}->{'vertical'}); } # ----------- sub show_debug { my ($str) = @_; # UNCOMMENT TO DEBUG # print "[DEBUG] $str\n"; }