You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GTK窗口无法居中,仅使用sudo启动程序时才生效

GTK窗口仅root权限下才能居中的问题

我编写的以下测试程序可正常编译链接,但只有通过sudo ./test以超级用户身份启动时,窗口才能实现居中效果。我制作了该极简示例以排查并解决问题,当前环境为Ubuntu 22.04、GTK 3.34。

测试代码

test.c

#include <gtk/gtk.h>

int main(int argc, char *argv[]) {
    
  GtkWidget *window;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "Center");
  gtk_window_set_default_size(GTK_WINDOW(window), 230, 150);
  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_widget_show(window);

  g_signal_connect(G_OBJECT(window), "destroy",
      G_CALLBACK(gtk_main_quit), NULL);

  gtk_main();

  return 0;
}

Makefile

# compiler
CC := gcc

# warnings
WARN := -Wall -Wno-deprecated-declarations

CCFLAGS=$(WARN)

GTKLIB=`pkg-config --cflags --libs gtk+-3.0`

# linker
LD=gcc
LDFLAGS= $(GTKLIB)

test: test.o
        $(LD) -o test test.o $(LDFLAGS)

test.o: test.c
        $(CC) -c    $(CCFLAGS) test.c $(GTKLIB) -o test.o

clean:
        rm -f *.o test

问题原因与解决方法

这个问题核心是GTK无法获取普通用户的显示器信息,导致GTK_WIN_POS_CENTER无法计算正确的居中位置。Ubuntu 22.04默认使用Wayland,普通用户可能因环境变量权限、Wayland后端限制等原因无法正常访问显示器配置。

解决步骤:

  • 检查XDG_RUNTIME_DIR权限:
    普通用户下执行echo $XDG_RUNTIME_DIR,确认目录所有者是当前用户(权限应为700)。若不是,执行:

    sudo chown -R $USER:$USER $XDG_RUNTIME_DIR
    
  • 强制使用X11后端:
    Wayland在部分场景下会限制程序的显示器访问权限,可强制GTK用X11后端运行:

    GDK_BACKEND=x11 ./test
    

    若有效,可将环境变量加入~/.bashrc永久生效:

    echo "export GDK_BACKEND=x11" >> ~/.bashrc
    source ~/.bashrc
    
  • 修复显示器配置文件权限:
    检查/var/lib/gdm3/.config/monitors.xml的权限,确保普通用户可读取:

    sudo chown root:gdm /var/lib/gdm3/.config/monitors.xml
    sudo chmod 640 /var/lib/gdm3/.config/monitors.xml
    sudo usermod -aG gdm $USER
    

    执行后重启系统生效。

  • 手动计算居中位置:
    如果上述方法无效,可绕过GTK的自动居中,手动计算屏幕尺寸来定位窗口。修改test.c中的代码,替换gtk_window_set_position为:

    GdkScreen *screen = gtk_window_get_screen(GTK_WINDOW(window));
    gint screen_width = gdk_screen_get_width(screen);
    gint screen_height = gdk_screen_get_height(screen);
    gtk_window_move(GTK_WINDOW(window), 
                    (screen_width - 230)/2, 
                    (screen_height - 150)/2);
    

    这种方式直接通过GDK获取屏幕参数,不受权限限制。

内容的提问来源于stack exchange,提问作者hometownjamie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 20:25:24