我有双显示器配置,希望所有新旧应用程序都在主显示器(右侧)上启动。但有些应用程序在第二个屏幕上启动,无论焦点/鼠标指针在哪里。我认为这是因为左上角 0:0 位于第二个显示器上。而且它比主显示器大,这可能是原因吗?
第二台是电视,我在上面运行 kodi,它有一个选择显示的设置。
可能有些应用程序会记住每个应用程序的位置和显示,并且还会在第二个应用程序关闭时进行处理 - 即记住位置直到显示器再次打开。在早期版本的 ubuntu compiz 中可以做到这一点,但现在不再如此。
更新:将 DE 改为 cinnamon
答案1
做好亲自动手的准备
我觉得我们可以要求用户做这些事情,但另一方面,当指示很明确时,为什么不呢?所以我们开始吧...
后台进程设置新窗口应出现在哪个监视器上
Vala 代码片段
using Wnck;
using Gdk;
using Gtk;
// compile:
// valac --pkg gtk+-3.0 --pkg gio-2.0 --pkg libwnck-3.0 -X "-D WNCK_I_KNOW_THIS_IS_UNSTABLE" 'file.vala'
namespace move_newwins {
private int[] monitor_geo_x;
private int[] monitor_geo_y;
private int monitorindex;
private string currmon;
private void getwins() {
var dsp = Gdk.Display.get_default();
unowned Wnck.Screen scr = Wnck.Screen.get_default();
scr.force_update();
get_monitors(dsp);
scr.window_opened.connect(newwin);
}
private void newwin (Wnck.Window newwin) {
newwin.unmaximize();
int winx;
int winy;
int winwidth;
int winheight;
newwin.get_geometry(out winx, out winy, out winwidth, out winheight);
Wnck.WindowType type = newwin.get_window_type();
if (type == Wnck.WindowType.NORMAL) {
newwin.set_geometry(
Wnck.WindowGravity.NORTHWEST,
Wnck.WindowMoveResizeMask.X |
Wnck.WindowMoveResizeMask.Y |
Wnck.WindowMoveResizeMask.WIDTH |
Wnck.WindowMoveResizeMask.HEIGHT,
monitor_geo_x[monitorindex] + 100,
monitor_geo_y[monitorindex] + 100,
winwidth, winheight
);
}
}
private int get_stringindex (string s, string[] arr) {
for (int i=0; i < arr.length; i++) {
if(s == arr[i]) return i;
} return -1;
}
private void get_monitors(Gdk.Display dsp) {
int nmons = dsp.get_n_monitors();
string[] monitornames = {};
for (int i=0; i < nmons; i++) {
Gdk.Monitor newmon = dsp.get_monitor(i);
monitornames += newmon.get_model();
Rectangle geo = newmon.get_geometry();
monitor_geo_x += geo.x;
monitor_geo_y += geo.y;
monitorindex = get_stringindex(
currmon, monitornames
);
}
}
public static void main (string[] args) {
currmon = args[1];
Gtk.init(ref args);
getwins();
Gtk.main();
}
}
Vala 代码片段需要编译。为此,您需要安装一些东西:
sudo apt install valac libwnck-3-dev libgtk-3-dev
复制以下代码片段,保存为
win_tomonitor.vala
使用以下命令编译该代码片段:
valac --pkg gtk+-3.0 --pkg gio-2.0 --pkg libwnck-3.0 -X "-D WNCK_I_KNOW_THIS_IS_UNSTABLE" '/path/to/win_tomonitor.vala'
(我知道,wnck 参数很愚蠢,但需要),工作目录中将生成一个可执行文件。
xrandr
通过在终端中运行命令来找出主显示器的名称。使用目标监视器作为参数运行可执行文件,例如
/path/to/win_tomonitor HDMI-1
新的(“正常”)窗口将出现在目标显示器左上角 100px(x + y)处。
注意:
将其添加为启动项时,您可能需要在运行之前暂停几秒钟。如果您在登录/启动时遇到问题,请告知。
编辑
以下是编辑后的版本(应要求提供)。区别:
- 此版本跳过对目标监视器上已有的窗口的操作。
此版本允许设置排除的
WM_CLASS
-es。要排除一个或多个类:添加额外的参数后目标监视器参数。例如:/path/to/win_tomonitor HDMI-1 Tilix Gedit
排除 Tilix 和 gedit 窗口的移动。
设置与第一个版本完全相同。玩得开心!
找出窗口的 WM_CLASS
- 打开终端窗口
- 类型
xprop
, 出版社Return - 点击目标窗口,
WM_CLASS
终端中出现
代码
using Wnck;
using Gdk;
using Gtk;
// compile:
// valac --pkg gtk+-3.0 --pkg gio-2.0 --pkg libwnck-3.0 -X "-D WNCK_I_KNOW_THIS_IS_UNSTABLE" 'file.vala'
namespace move_newwins {
private int[] monitor_geo_x;
private int[] monitor_geo_y;
private int monitorindex;
private string currmon;
Gdk.Display dsp;
string[] blacklist;
private void getwins() {
dsp = Gdk.Display.get_default();
unowned Wnck.Screen scr = Wnck.Screen.get_default();
scr.force_update();
get_monitors(dsp);
scr.window_opened.connect(newwin);
}
private void newwin (Wnck.Window newwin) {
newwin.unmaximize();
int winx;
int winy;
int winwidth;
int winheight;
newwin.get_geometry(out winx, out winy, out winwidth, out winheight);
string wins_monitor = dsp.get_monitor_at_point(winx, winy).get_model();
Wnck.WindowType type = newwin.get_window_type();
string wm_class = newwin.get_class_group_name();
bool blacklisted = get_stringindex(wm_class, blacklist) != -1;
if (
type == Wnck.WindowType.NORMAL &&
wins_monitor != currmon &&
!blacklisted
) {
newwin.set_geometry(
Wnck.WindowGravity.NORTHWEST,
Wnck.WindowMoveResizeMask.X |
Wnck.WindowMoveResizeMask.Y |
Wnck.WindowMoveResizeMask.WIDTH |
Wnck.WindowMoveResizeMask.HEIGHT,
monitor_geo_x[monitorindex] + 100,
monitor_geo_y[monitorindex] + 100,
winwidth, winheight
);
}
}
private int get_stringindex (string s, string[] arr) {
for (int i=0; i < arr.length; i++) {
if(s == arr[i]) return i;
} return -1;
}
private void get_monitors(Gdk.Display dsp) {
int nmons = dsp.get_n_monitors();
string[] monitornames = {};
for (int i=0; i < nmons; i++) {
Gdk.Monitor newmon = dsp.get_monitor(i);
monitornames += newmon.get_model();
Rectangle geo = newmon.get_geometry();
monitor_geo_x += geo.x;
monitor_geo_y += geo.y;
monitorindex = get_stringindex(
currmon, monitornames
);
}
}
public static void main (string[] args) {
currmon = args[1];
blacklist = args[1:args.length];
Gtk.init(ref args);
getwins();
Gtk.main();
}
}
答案2
您想要更简单的答案吗?在“设置”下的外观/码头, 放显示到所有显示。
单击图标所在的显示屏即为打开窗口的显示屏。
答案3
您想要简单的答案吗?
- 打开应用程序并转到打开它的屏幕。
- 最大化它,然后恢复它(窗口化它)。
- 将其拖到您想要打开的屏幕上,最大化它,然后关闭它。
下次每次打开应用程序时,它都会出现在正确的屏幕上。