Как запускать приложения всегда на определенном дисплее?

11

У меня конфигурация с двумя дисплеями, и я хочу, чтобы все новые и старые приложения запускались на основном дисплее, который находится справа. Но некоторые приложения запускаются на втором экране, независимо от того, где находится фокус / указатель мыши. Я думаю, что это потому, что верхний: левый угол 0: 0 находится на втором мониторе. И это больше, чем основной, это может быть причиной?

Вторичным является телевизор, на котором я запускаю коди, в котором есть настройка для выбора отображения.

Может быть, есть какое-то приложение, которое запоминает для каждой позиции приложения и дисплея, а также позаботится, когда секундная стрелка выключена - запоминайте положение, пока монитор снова не включится. В более ранних версиях Ubuntu Compiz делали это, но не более.

Обновление: изменен DE на корицу

LeonidMew
источник
Я тоже ищу это, тебе повезло?
Фелипе
@Felipe Не повезло
LeonidMew
В списке приложений в Cinnamon, у меня есть пункт меню, чтобы переместить приложение на другой монитор, это полезно, особенно когда вторичный выключен. Но это не решение вопроса.
LeonidMew
1
Решением может быть небольшой процесс, похожий на deamon, чтобы следить за новыми окнами, перемещать их на основной экран. Будет ли это приемлемым решением? Вы бы, вероятно, даже не увидели, как это было перемещено.
Джейкоб Влейм
@JacobVlijm Да, это может быть решением. Но я не знаю, как это написать, не могли бы вы дать две части кода - как определить новое окно и как переместиться
LeonidMew

Ответы:

13

Будьте готовы запачкать руки
На краю того, что я чувствую, мы могли бы попросить пользователей сделать, но с другой стороны, когда инструкции ясны, почему бы и нет? Итак, поехали ...


Фоновый процесс, чтобы установить, на каком мониторе должны появляться новые окна

Вала фрагмент

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();
    }
}
  1. Фрагмент Vala должен быть скомпилирован. Для этого вам нужно установить несколько вещей:

    sudo apt install valac libwnck-3-dev libgtk-3-dev
    
  2. Скопируйте фрагмент ниже, сохраните его как win_tomonitor.vala

  3. Скомпилируйте фрагмент с помощью команды:

    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 глуп, но необходим), исполняемый файл будет создан в рабочем каталоге.

  4. Узнайте имя вашего основного монитора, запустив команду xrandrв терминале.
  5. Запустите исполняемый файл с целевым монитором в качестве аргумента, например

    /path/to/win_tomonitor HDMI-1
    

Новые ("нормальные") окна появятся на 100px (x + y) от вершины целевого монитора.

NB

При добавлении этого в качестве элемента автозагрузки может потребоваться добавить перерыв в несколько секунд, прежде чем запускать его. Если у вас возникли проблемы при входе в систему / запуске, пожалуйста, укажите.


РЕДАКТИРОВАТЬ

Ниже отредактированная версия (по запросу). Отличия:

  • Эта версия пропускает действие на окнах, которые уже находятся на целевом мониторе.
  • Эта версия позволяет установить исключенные 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();
    }
}
Якоб Влейм
источник
Команда valac не найдена. Когда я пытаюсь установить его с помощью apt install valac, скрипт не находит некоторые IP-адреса
Родольфо Веласко