Як запускати програми завжди на певному дисплеї?


11

Я маю подвійну конфігурацію дисплея, і хочу, щоб усі нові та старі програми починалися на первинному дисплеї, який знаходиться праворуч. Але деякі програми запускаються на другому екрані, незалежно від того, де знаходиться фокус / вказівник миші. Я думаю, це тому, що верхній: лівий кут 0: 0 знаходиться на другому моніторі. І це більше, ніж первинне, чи може це бути причиною?

Вторинний - це телевізор, де я запускаю коді, які мають налаштування вибору дисплея.

Можливо, є кілька додатків, які запам'ятовуються для кожної позиції та дисплея програми, а також слідкуйте за тим, коли секунду вимкнено - середню позицію запам'ятовування, поки монітор знову не буде включений. У більш ранніх версіях ubuntu compiz роблять це, але не більше.

Оновлення: Змінено DE на корицю


Я теж це шукаю, чи пощастило?
Феліпе

@Felipe Не пощастило
LeonidMew

У списку програм із корицею, у мене є можливість переміщення програми на інший монітор, його корисно, особливо коли вторинне вимкнено. Але це не вирішення питання.
LeonidMew

1
Рішення може бути демамон-подібним процесом, щоб слідкувати за новими вікнами, переміщувати їх на основний екран. Це було б прийнятним рішенням? Ви, мабуть, навіть не бачили, щоб його рухали.
Яків Влійм

@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
    

Нові ("звичайні") вікна з'являться на 100 пікселів (х + у) від топлету цільового монітора.

NB

Додаючи це як елемент запуску, можливо, вам доведеться додати перерву в кілька секунд, перш ніж запустити його. Якщо у вас виникли проблеми при вході / запуску, будь ласка, зазначте.


EDIT

Нижче відредагована версія (за запитом). Відмінності:

  • Ця версія пропускає дії на вікна, які вже є на цільовому моніторі.
  • Ця версія дозволяє встановлювати виключені 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-адрес
Rodolfo Velasco
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.