summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--lib/Xconfig/main.pm3
-rw-r--r--lib/Xconfig/xfree.pm8
-rwxr-xr-xtools/XFdrake11
4 files changed, 22 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index bf3618f..177694d 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,4 @@
+- handle resolution switch via xrandr without restarting X (#30896)
- add 1366x768, 1360x768 and 1360x765 resolutions
- add big standard resolutions (4/3, 16/10, 16/9)
- [bugfix] fix test message not translated (#30261)
diff --git a/lib/Xconfig/main.pm b/lib/Xconfig/main.pm
index 7fb9c8a..6a4c8cf 100644
--- a/lib/Xconfig/main.pm
+++ b/lib/Xconfig/main.pm
@@ -209,12 +209,15 @@ The current configuration is:
sub write {
my ($raw_X, $X) = @_;
export_to_install_X($X) if $::isInstall;
+ my $only_resolution = $raw_X->is_only_resolution_modified;
$raw_X->write;
Xconfig::various::check_XF86Config_symlink();
symlinkf "../../usr/bin/Xorg", "$::prefix/etc/X11/X";
if ($X->{resolutions}[0]{bios}) {
Xconfig::various::setupFB($X->{resolutions}[0]{bios});
'need_reboot';
+ } elsif (my $resolution = $only_resolution && eval { $raw_X->get_resolution }) {
+ 'need_xrandr' . sprintf(' --size %dx%d', @$resolution{'X', 'Y'});
} else {
'need_restart';
}
diff --git a/lib/Xconfig/xfree.pm b/lib/Xconfig/xfree.pm
index 519f2ea..a3dda06 100644
--- a/lib/Xconfig/xfree.pm
+++ b/lib/Xconfig/xfree.pm
@@ -73,6 +73,10 @@ sub is_modified {
my ($raw_X) = @_;
$raw_X->{before} ne $raw_X->prepare_write;
}
+sub is_only_resolution_modified {
+ my ($raw_X) = @_;
+ ($raw_X->{after_set_resolutions} || $raw_X->{before}) eq $raw_X->prepare_write;
+}
sub empty_config {
my ($class) = @_;
$class->new(Xconfig::parse::read_XF86Config_from_string(our $default_header));
@@ -198,6 +202,7 @@ sub set_resolutions {
my ($raw_X, $resolutions, $o_Screen) = @_;
my $Depth = $resolutions->[0]{Depth} eq '32' ? 24 : $resolutions->[0]{Depth};
+ my $only_resolution = $raw_X->is_only_resolution_modified;
foreach my $Screen ($o_Screen ? $o_Screen : $raw_X->get_Sections('Screen')) {
$Screen ||= $raw_X->get_default_screen or internal_error('no screen');
@@ -209,12 +214,15 @@ sub set_resolutions {
my @Modes = map { sprintf($Mode_name eq 'Modes' ? '"%dx%d"' : '%d %d', @$_{'X', 'Y'}) } @l;
delete $Screen->{DefaultDepth};
+ $only_resolution &&= $Screen->{DefaultColorDepth} && $Screen->{DefaultColorDepth}{val} eq $Depth;
$Screen->{DefaultColorDepth} = { val => $Depth };
$Screen->{Display} = [ map {
{ l => { Depth => { val => $_ }, $Mode_name => { val => join(' ', @Modes) } } };
} 8, 15, 16, 24 ];
}
add_gtf_ModeLines($raw_X, $resolutions);
+
+ $raw_X->{after_set_resolutions} = $only_resolution ? $raw_X->prepare_write : '';
}
diff --git a/tools/XFdrake b/tools/XFdrake
index 19988f3..e9e2b61 100755
--- a/tools/XFdrake
+++ b/tools/XFdrake
@@ -56,7 +56,16 @@ $configure_this ||= $::auto ? 'auto_install' : 'everything';
}
};
if (!$::auto) {
- if ($rc eq 'need_restart') {
+ if ($rc =~ /need_xrandr(.*)/) {
+ my $opts = $1;
+ my $before = `xrandr`;
+ run_program::run('xrandr', split(' ', $opts));
+ my $after = `xrandr`;
+ if ($before eq $after) {
+ log::l("xrandr $opts failed, defaulting to ask_for_X_restart");
+ any::ask_for_X_restart($in);
+ }
+ } elsif ($rc eq 'need_restart') {
any::ask_for_X_restart($in);
} elsif ($rc eq 'need_reboot') {
$in->ask_warn('', N("You need to reboot for changes to take effect"));