LINUX.ORG.RU

Определение Window Manager - это правильный способ или можно лучше?

 , ,


2

2

Макнули тут носом в старый топик: у человека не грузится программа на java.

Проблема была в том, что у него на десктопе нестандартный window manager - DWM. Под другим всё работает.

Решение внезапно нашлось на Арчевики - оказывается, в Жабе есть огромный захардкоженый список window managers, и если скачать специальную утилиту и временно переименоваться из DWM в LG3D, то всё заработает.

Заинтригованный, полез я смотреть, что лучшие в мире разработчики джавы накодили внутри, и обнаружил вот такие чудесные моменты:

самая соль здесь: https://gist.github.com/olegchir/65f39ddb73f01107625338c26da84231

а вот здесь вообще весь файл (смотреть не обязательно, только если хочется почувствовать контекст): https://gist.github.com/olegchir/fcaa55dba359e10e093ff045d3916037

как тут же подсказали друзья, мы не одиноки во вселенной, и в android существует чем-то идейно похожий класс на восемь тысяч строчек: https://github.com/android/platform_frameworks_base/blob/master/services/core...

возникает несколько вопросов

- вы согласны с таким алгоритмом перебора Window Managers? Если нет, как бы сделали эту задачу вы?

- зачем нужны эти лютейшие цепочки из if'ов? Неужели нельзя оформить всё в виде паттерна стратегия? Или такое сокращение убьёт весь перфоманс? Особенно этот вопрос актуален для километрового файла на Андроиде..

★★★★☆

Последнее исправление: stevejobs (всего исправлений: 1)

«Исторически сложилось»

vertexua ★★★★★
()

Какую задачу-то решить пытались?

Можно для Ъ — нахрена вообще перебирать WM?

Deleted
()
Ответ на: Какую задачу-то решить пытались? от Deleted

Удваиваю. Java-господа вообще любят рассказывать про то, что они раз написали - и это потом абсолютно везде работает, так какая им разница что за DE, WM, ОС и прочее? Без IDE и поллитры в том куске с гитхаба не понятно зачем вообще эти проверки нужны.

alozovskoy ★★★★★
()
Ответ на: Какую задачу-то решить пытались? от Deleted

Всё это ради функции getWMID() (возвращающей айдишник текущего WM)

А наличие айдишника и перебор по нему - ради вот таких проверок:

    static boolean isNonReparentingWM() {
        if (awtWMNonReparenting == -1) {
            awtWMNonReparenting = (XToolkit.getEnv("_JAVA_AWT_WM_NONREPARENTING") != null) ? 1 : 0;
        }
        return (awtWMNonReparenting == 1 || XWM.getWMID() == XWM.COMPIZ_WM
                || XWM.getWMID() == XWM.LG3D_WM || XWM.getWMID() == XWM.CWM_WM);
    }

Re-parenting - это из иксовой терминологии, вот статья: https://en.wikipedia.org/wiki/Re-parenting_window_manager

И соответственно дальше на это делаются проверки типа:

/*
         * Some window managers configure before we are reparented and
         * the send event flag is set! ugh... (Enlighetenment for one,
         * possibly MWM as well).  If we haven't been reparented yet
         * this is just the WM shuffling us into position.  Ignore
         * it!!!! or we wind up in a bogus location.
         */
        int runningWM = XWM.getWMID();

        if (!isReparented() && isVisible() && runningWM != XWM.NO_WM
                &&  !XWM.isNonReparentingWM()
                && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
            insLog.fine("- visible but not reparented, skipping");
            return;
        }
stevejobs ★★★★☆
() автор топика
Ответ на: комментарий от stevejobs

Ну, это всё еще не отвечает на вопрос, какую задачу хотели решить.

Какая-то шизофазия в коде. Почему-то у остальных тулкитов такой проблемы нет, и только у java, внезапно...

Deleted
()

алгоритм действий:

1) переписываешь с использованием Стратегии 2) собираешь 3) делаешь бенчмарки 4) подымаешь волну в сообществе 5) пропихиваешь патч в апстрим 6) ....

второй алгоритм:

1) переписываешь без использования определения менеджера (всегда валидный ответ 2) собираешь 3) делаешь замеры (где не работает, стотит ли усилий 4) подымаешь волну в сообществе 5) пропихиваешь патч в апстрим ) ....

ныть на лоре не стоит, стоит действовать или сопеть в платочек, русский иван ничем не лучше индуса в этом контексте, как не крути

anonymous
()
Ответ на: комментарий от Deleted

кто-то делал реализацию и счел такой алгоритм правильнее\проще, предложите свою реализацию и несколько научных публикаций для ее обоснования, выпустите парралельную сборку (форк) если вам это так мешает, если все плохо и неверно, сообщество само решит, кто умнее, индусы из сан или вы (результат думаю заранее очевиден)

anonymous
()
Ответ на: комментарий от anonymous

Люди совсем читать разучились

предложите свою реализацию

Реализацию чего?

Deleted
()
Ответ на: комментарий от Deleted

насколько понял комментарий - на основе информации, включён ли re-parenting, считаются координаты окна, чтобы случайно не нарисовать его со сдвигом. Это актуально для WM не использующих декораций типа xmonad или compiz который рисует декорации отдельно от окна

откуда инфа, что в других тулкитах не написано такой же лапши? :3

stevejobs ★★★★☆
() автор топика
Ответ на: комментарий от stevejobs

Ну, сколько ковырялся в гтк, такой фигни не видел. Хотя зуб не дам.

считаются координаты окна, чтобы случайно не нарисовать его со сдвигом

Задача приложения — рисовать в своё окно, а не заниматься какой-то фигнёй с координатами окна. Я не исключаю, что я что-то серьёзно упускаю, но практический смысл таких манипуляций от меня ускользает.

Deleted
()

Если кого-нибудь интересует определятор для C++, он есть в коде QMMP.

ZenitharChampion ★★★★★
()
Ответ на: комментарий от Deleted

то что выше - это не прикладной код, это как раз тот тулкит, который позволяет приложению «просто рисовать своё окно, а не заниматься какой-то фигнёй», оно под капотом фиксит все эти проблемы. Само приложение ничего о сдвигах и прочей фигне не знает

понятно что для части вещей можно использовать внешние либы, типа «wmctrl -m». Но это не портабельное решение. Разве что переписать часть кода wmctrl на жабе. И тут снова вопрос - как это делать правильно. Например, возможно уже есть какие-то стандарты от freedesktop, позволяющие получить свойства WM стандартизованным способом

и если таких стандартов нет, то как блин десктопный линукс вообще живет-то

stevejobs ★★★★☆
() автор топика
Последнее исправление: stevejobs (всего исправлений: 3)
Ответ на: комментарий от stevejobs

Ну я и говорю о тулките. Окно есть — можно рисовать. Как это со времён motif делалось, принципиально ничего не поменялось. WM в этом никак не участвует.

оно под капотом фиксит все эти проблемы

Ну или создаёт, судя по ОП.

Deleted
()
Ответ на: комментарий от stevejobs

и если таких стандартов нет, то как блин десктопный линукс вообще живет-то

Всё есть. ICCCM + NETWM.

Вот потому я и в недоумении.

Deleted
()
Ответ на: комментарий от Deleted

Еще немножко комментариев

  * No selection owner, but, perhaps it is not ICCCM compliant WM
  * (e.g. CDE/Sawfish).

и еще

    /*
     * Is CDE running?
     *
     * XXX: This is hairy...  CDE is MWM as well.  It seems we simply test
     * for default setup and will be bitten if user changes things...
     *
     * Check for _DT_SM_WINDOW_INFO(_DT_SM_WINDOW_INFO) on root.  Take the
     * second element of the property and check for presence of
     * _DT_SM_STATE_INFO(_DT_SM_STATE_INFO) on that window.
     *
     * XXX: Any header that defines this structures???
     */

Всё есть. ICCCM + NETWM.

Ну вот вижу, что имена и так получаются через NETWM, например:

static boolean isKDE2() {
    return isNetWMName("KWin");
}

А вот уже capabilities типа набившего в этом топике оскомину репарентинга или extended state - уже закожены внутри if'ов

Где согласно ICCCM дожна храниться мета-информация о возможностях WM?

например вот как тут проверяется, что Metacity не может организовать фичу «максимизировать только по горизонтали, а не на весь экран»:

    @SuppressWarnings("fallthrough")
    boolean supportsExtendedState(int state) {
...
case Frame.MAXIMIZED_HORIZ:
              /*
               * WMs that talk NET/WIN protocol, but do not support
               * unidirectional maximization.
               */
              if (getWMID() == METACITY_WM) {
                  /* "This is a deliberate policy decision." -hp */
                  return false;
              }
stevejobs ★★★★☆
() автор топика
Ответ на: комментарий от stevejobs

Где согласно ICCCM дожна храниться мета-информация о возможностях WM?

_NET_SUPPORTED

например вот как тут проверяется, что Metacity не может организовать фичу «максимизировать только по горизонтали, а не на весь экран»:

Тут да. Упоротость гномеров составители NETWM не смогли предусмотреть. С точки зрения протокола, «максимизировать во все стороны» — это комбинация _NET_WM_ACTION_MAXIMIZE_HORZ и _NET_WM_ACTION_MAXIMIZE_VERT. Обычно, даже если у WM нет такой кнопки в гуе, послав событие вручную, можно максимизировать окно в одном направлении. Это стандартная фича.

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

Deleted
()
Ответ на: комментарий от alozovskoy

Java-господа вообще любят рассказывать про то, что они раз написали - и это потом абсолютно везде работает

Ну мы к этому стремимся, по крайней мере.

так какая им разница что за DE, WM, ОС и прочее?

Java-господам, обычно, без разницы. Вот как раз для этого гномики из сана это и понаписали, чтобы белые господа не заморачивались на проблемы совместимости.

Без IDE и поллитры в том куске с гитхаба не понятно зачем вообще эти проверки нужны.

Какие-то странные вопросы у тебя. Ты ещё спроси, зачем JVM на Windows и Linux разная скачивается. Разные WM, разные глюки, разные воркэраунды. Вчитайся в код и поймёшь, зачем. Учти, что код писался лет 20 назад, возможно сейчас появились способы получше и поуниверсальней, но то, что работает, переписывать глупо.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Ну мы к этому стремимся, по крайней мере.

Сама реализация этой идеи говорит о том, что этого никогда не получится. Точнее - вам все равно нужна jvm, так то можно сказать что и на каком-нибудь bash код кроссплатформенный.

Разные WM, разные глюки, разные воркэраунды.

Вот я правда не понимаю зачем эти проверки. И, судя по всему, как раз из-за них и нужны эти воркэраунды, при этом это не код старый, такая шняга с большинством java-софта в немейнстримовых DE, то есть проще один раз при старте сессии подменять имя wm и не париться. И что проверяется, то есть какая, по сути, разница, что там отрисует окошко? Почему в других тулкитах этого нет (или я не прав?)?

alozovskoy ★★★★★
()
Ответ на: комментарий от alozovskoy

да, GNU - кроссплатформенный. Можешь установить на комп GNU/Windows (Cygwin, Msys, Msys2) и радоваться

Вот я правда не понимаю зачем эти проверки.

Выше же написал, зачем нужны эти проверки.

Предложи способ реализовать это лучше, пожалуйста. (Как минимум, как бы ты решил перечисленное выше: репарентинг, не совместимые с ICCCM WM типа CDE/Sawfish, отсутствие у Metacity возможности растягивать окно в одном направлении и отсутствие этого поля в ICCCM)

и да, я не поддерживаю маркобесия типа «работает не трогай», о котором говорит Legioner, но я вчера потратил несколько часов на распутывание лапши и (в том числе в силу отстутсвия там нормальных тестов) склоняюсь что рефакторинг должен выглядеть как полное переписывание всего :(

Почему в других тулкитах этого нет (или я не прав?)?

другие тулкиты могут юзать ту же функциональность, но размазанный по утилитам типа wmctrl -m. В жабе так нельзя, жаба не может юзать какие-то внешние утилиты. Поэтому этот кусок кода прямо в ней находится. Олсо, что находится внутри wmctrl, и как оно будет работать с не EWMH/NetWM WM непонятно (а кусок говнокода выше работает вообще со всем)

stevejobs ★★★★☆
() автор топика
Последнее исправление: stevejobs (всего исправлений: 4)
Ответ на: комментарий от alozovskoy

такая шняга с большинством java-софта в немейнстримовых DE

напиши хотя бы пять java софтин, которыми ты пользуешься каждый день

TERRANZ ★★★★
()
Ответ на: комментарий от alozovskoy

то есть проще один раз при старте сессии подменять имя wm и не париться

эту проблему можно решить просто: скажем, пусть в ~/.config/javaPrefs/WM лежит дескриптор текущего WM, и в нем должны быть записаны его возможности типа репарентинга, типа отрисовки декораций. Типа «стандарт на нестандартные ворзможности».

или по-другому, пусть в /usr/lib/javaPrefs/WM лежат такие дескрипторы для всех установленных в системе WM. Файлы с ними готовят мантейнеры (благо сделать такой файл - считаные минуты). Файлы называются как WM ID. Жабка определяет WM ID как-то самостоятельно, а вот все настройки уже берет из дескрипторов

сам код желательно тоже отрефакторить на паттерн стратегия/плагин. Сделать базовый класс типа WMPlugin, в котором есть дефолтная реализация с автопоиском возможностей. В зависимости от наличия файла-дескриптора возможностей WM, некоторые методы будут подменяться на константы из этого файла. Плюс весь код специфичный для конкретных WM нужно перенести в классы-наследники WMPlugin

более того, неплохо бы, чтобы создатели WM сами могли писать такие плагины и подкладывать их внешним образом. Да хоть туда же в javaPrefs/WM подкладывать скомпилированные классы-наследники WMPlugin называющиеся как WM ID, и потом при старте жабка (точнее AWT) будет динамически грузить их в отдельный класслоадер, желательно в OSGi

stevejobs ★★★★☆
() автор топика
Последнее исправление: stevejobs (всего исправлений: 1)
Ответ на: комментарий от TERRANZ

Стараюсь обходить java стороной, так что из ежедневного у меня только Squirrel. Так ловил те же проблемы на веблоджиковом инсталлере и какой-то ide типа идеи. Может еще что-то было, но сейчас не вспомню, так как давно закостылил.

alozovskoy ★★★★★
()
Ответ на: комментарий от stevejobs

Я понимаю что это, в целом, решаемо, и частично явлеятся ограничением выбранной платформы. Просто есть же костыли, которые заставляют гарантированно работать java-приложения в любых wm уровня awesome\i3\qtile\etc, почему бы не использовать это все по дефолту? Ждать пока каждый разраб\мейнтейнер очередного wm сделает нормальный конфиг для интеграции java мне кается не принесет успеха, а вот выставить дефолтные значения, которые гарантированно будут работать везде (пусть и в ущерб какому-то функционалу) мне кажется можно.

alozovskoy ★★★★★
()
Ответ на: комментарий от alozovskoy

Сама реализация этой идеи говорит о том, что этого никогда не получится.

У нас уже получилось, мы пользуемся и зарабатываем деньги.

Точнее - вам все равно нужна jvm

Угу, а ещё процессор, оперативная память и одна из поддерживаемых операционных систем. Обычно это не проблема.

так то можно сказать что и на каком-нибудь bash код кроссплатформенный.

Можно. Кто-то спорить будет что-ли?

Вот я правда не понимаю зачем эти проверки. И, судя по всему, как раз из-за них и нужны эти воркэраунды, при этом это не код старый, такая шняга с большинством java-софта в немейнстримовых DE, то есть проще один раз при старте сессии подменять имя wm и не париться. И что проверяется, то есть какая, по сути, разница, что там отрисует окошко?

Ну вот запускал я в убунте под компизом лет 10 назад приложение на Java, а оно мне пустое окошко рисовало. Грохаешь компиз — работает. Подозреваю, что где-то в этих if-ах добавился код, чтобы обходить глюки того компиза.

Почему в других тулкитах этого нет (или я не прав?)?

Да есть, скорее всего, или они пока не напоролись на те баги, которые обходит JVM.

Legioner ★★★★★
()
Ответ на: комментарий от stevejobs

С чего ты взял? В копирайте вот 2003 написано. Если ты про первый коммит, то там всё скопом залито, а где оно до этого было — я хз.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Подозреваю, что где-то в этих if-ах добавился код, чтобы обходить глюки того компиза.

Или то был баг где-то в этих самых if-ах.

legolegs ★★★★★
()
Ответ на: комментарий от alozovskoy

в любых wm уровня awesome\i3\qtile\etc, почему бы не использовать это все по дефолту?

потому что дефолты настроены на какой-то мрак типа CDE/Sawfish :) Как верно подметил Legioner там в копирайте 2003 год, в это время было актуально чтобы работало на вот этих динозаврих поделиях, да на втором гнуме и вторых кедах. А после этого на Жабу вообще забили как на средство разработки десктопных приложений

stevejobs ★★★★☆
() автор топика
Последнее исправление: stevejobs (всего исправлений: 1)
Ответ на: комментарий от Legioner

Ну вот запускал я в убунте под компизом лет 10 назад приложение на Java, а оно мне пустое окошко рисовало. Грохаешь компиз — работает. Подозреваю, что где-то в этих if-ах добавился код, чтобы обходить глюки того компиза.

Если всё под компизом работает, а java — нет, это не «глюки компиза». Тут не «глюки компиза» исправлять надо, а свой тулкит фиксить. А не подпирать его костылями.

Deleted
()
Ответ на: комментарий от Deleted

господь и сжег - появился JavaFX

но емнип в нём всё равно есть куски AWT :3

например, глянь sun.awt.AppContext: в кормментариях AWT inside Swing inside JavaFX :)

synchronized (getAppContextLock) {
                        if (numAppContexts.get() == 0) {
                            if (System.getProperty("javaplugin.version") == null &&
                                    System.getProperty("javawebstart.version") == null) {
                                initMainAppContext();
                            } else if (System.getProperty("javafx.version") != null &&
                                    threadGroup.getParent() != null) {
                                // Swing inside JavaFX case
                                SunToolkit.createNewAppContext();
                            }
                        }
                    }
stevejobs ★★★★☆
() автор топика
7 апреля 2017 г.

На сегодняшнем JPoint один товарищ в докладе как раз рассказывал про этот алгоритм, не ты ли это был?

hippi90 ★★★★★
()
Ответ на: комментарий от hippi90

А, ты из сбт? Ну вот сижу, жду когда меня придут бить ногами коллеги, с чем-то несогласные. Но в чате гильдии пока шторма не поднялось, еще есть время выпить последнюю чашку чая :)

stevejobs ★★★★☆
() автор топика
Ответ на: комментарий от Deleted

а не заниматься какой-то фигнёй с координатами окна. Я не исключаю, что я что-то серьёзно упускаю, но практический смысл таких манипуляций от меня ускользает.

Запустить окно диалога в центре окна приложения, а не там где это вздумается WM. Для этого нужно оперировать координатами. Все тулкиты так делают, даже SDL2.

EXL ★★★★★
()
Ответ на: комментарий от stevejobs

Не угадал, я работаю в «Синимекс Воронеж»)

hippi90 ★★★★★
()
Ответ на: комментарий от TERRANZ

напиши хотя бы пять java софтин, которыми ты пользуешься каждый день

Я могу. JSampler, Matlab, Scilab, TuxGuitar, FreeMind.

curufinwe ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.