Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: IGHOR от Июнь 19, 2008, 03:25



Название: Bring window to front
Отправлено: IGHOR от Июнь 19, 2008, 03:25
Написал вювер картинок: http://ighor.info/JulyViewRC1.rar
вот соткнулся с проблемой, если окно с картинкой под окнами нужно перевести его на передний план.
По дабл клику на иконке в трею я делаю окно hide(), потом он топ а потом обратно в нормальное состояние и show() , тогда работает. Но такой метод не подходит к если связать разшырения файлов с прогой, и запускать файлы картинок, после етого окно картинки остается за окнами.
Каким способом можно перевести окно на передний план ?


Название: Re: Bring window to front
Отправлено: sendevent от Июнь 19, 2008, 17:24
QApplication::setActiveWindow ( QWidget * active ) | QWidget::activateWindow()?


Название: Re: Bring window to front
Отправлено: IGHOR от Июнь 19, 2008, 20:44
QApplication::setActiveWindow(this);
не работает, то же самое.
Но Спасибо за ответ:)


Название: Re: Bring window to front
Отправлено: Sergeich от Июнь 19, 2008, 21:05
QWidget::raise()


Название: Re: Bring window to front
Отправлено: IGHOR от Июнь 20, 2008, 13:54
QWidget::raise()
Не помагает


Название: Re: Bring window to front
Отправлено: Sergeich от Июнь 21, 2008, 00:27
Но такой метод не подходит к если связать разшырения файлов с прогой, и запускать файлы картинок, после етого окно картинки остается за окнами.
Каким способом можно перевести окно на передний план ?
А каким образом происходит запуск? Ты используешь что-нить типа SingleApplication?


Название: Re: Bring window to front
Отправлено: IGHOR от Июнь 22, 2008, 19:54
Но такой метод не подходит к если связать разшырения файлов с прогой, и запускать файлы картинок, после етого окно картинки остается за окнами.
Каким способом можно перевести окно на передний план ?
А каким образом происходит запуск? Ты используешь что-нить типа SingleApplication?

Да использую SingleApplication


Название: Re: Bring window to front
Отправлено: ритт от Июнь 23, 2008, 00:45
Код:
void activateMainWidget()
{
    QWidgetList widgets = QApplication::allWidgets();
    if (!widgets.isEmpty()) {
        QWidget *w = widgets.at(0);
        w->setWindowState(w->windowState() & ~Qt::WindowMinimized);
        w->raise();
        w->activateWindow();
    }
}
специально не стал включать данный код в сингаппликэйшен, т.к. не имеет прямого отношения к задаче


Название: Re: Bring window to front
Отправлено: Sergeich от Июнь 23, 2008, 11:37
Добавь перед посылкой сообщения экземпляру приложения
Код:
#ifdef Q_WS_WIN
AllowSetForegroundWindow( ASFW_ANY );
#endif


Название: Re: Bring window to front
Отправлено: IGHOR от Июль 04, 2008, 22:16
Код:
void activateMainWidget()
{
    QWidgetList widgets = QApplication::allWidgets();
    if (!widgets.isEmpty()) {
        QWidget *w = widgets.at(0);
        w->setWindowState(w->windowState() & ~Qt::WindowMinimized);
        w->raise();
        w->activateWindow();
    }
}
специально не стал включать данный код в сингаппликэйшен, т.к. не имеет прямого отношения к задаче

Ноль реакции

Добавь перед посылкой сообщения экземпляру приложения
Код:
#ifdef Q_WS_WIN
AllowSetForegroundWindow( ASFW_ANY );
#endif

Когда вставляю код выдает ошибку: ни AllowSetForegroundWindow ни ASFW_ANY не найдено.


Название: Re: Bring window to front
Отправлено: Racheengel от Ноябрь 19, 2008, 12:14
Похожая фигня у меня сейчас (кути 4.4) - под виндой набор

        w->show();
        w->raise();
        w->activateWindow();  // это должно быть обязательно после show()

работает, но под КДЕ не хочет.


Название: Re: Bring window to front
Отправлено: Racheengel от Ноябрь 20, 2008, 11:24
Фигня однако...
Под Х11 raise() не пашет напрочь.
Qt::WindowStaysOnTopHint помогает, НО после этого окно всегда висит поверх других.
Убирание этого флага приводит к скрытию окна.

Короче отправил тролям багрепорт.


Название: Re: Bring window to front
Отправлено: Alex Custov от Ноябрь 20, 2008, 12:30
а буквально несколькими строками ниже... http://www.prog.org.ru/topic_7851_0.html
про netwm написано тут: http://www.linux.org.ru/wiki/en/NETWM


Название: Re: Bring window to front
Отправлено: Alex Custov от Ноябрь 20, 2008, 12:33
работает, но под КДЕ не хочет.

ты наверно даже не читал, что я написал в ветке про активное окно  ;D


Название: Re: Bring window to front
Отправлено: Racheengel от Ноябрь 20, 2008, 15:01
Нет, почему, я пробовал справиться с проблемой функциями Х11.
Например, XRaiseWindow().
Однако это не помогло :(
Можно поподробнее, что значит "дернуть атом _NET_ACTIVE_WINDOW"?  Имеется в виду XSendEvent() ?

Да, ветки наверное стоит склеить :) А то тема одна и та же.


Название: Re: Bring window to front
Отправлено: Alex Custov от Ноябрь 20, 2008, 15:31
Нет, почему, я пробовал справиться с проблемой функциями Х11.
Например, XRaiseWindow().
Однако это не помогло :(

WM может не позволить это сделать.

Можно поподробнее, что значит "дернуть атом _NET_ACTIVE_WINDOW"?  Имеется в виду XSendEvent() ?
Да, ветки наверное стоит склеить :) А то тема одна и та же.

Код:
climsg(winId(), NET_ACTIVE_WINDOW, 2, CurrentTime);

примеры есть по ссылке на лоре.


Название: Re: Bring window to front
Отправлено: Racheengel от Ноябрь 20, 2008, 15:56
ок, спасибо, попробую вечером.
потом отпишусь :)


Название: Re: Bring window to front
Отправлено: Racheengel от Ноябрь 21, 2008, 01:29
Alex Custov, все заработало, большой данке шен за помошь :)
Немного пришлось напильничком обточить, но в общем то что надо :)
Правда не знаю, как с этим делом на маке, но под сузей в КДЕ и гноме пашет.
Что странно - троллевский саппорт ничего дельного так и не предложил...
ИМХО есть смысл таки на вику забросить.


Название: Re: Bring window to front
Отправлено: Alex Custov от Ноябрь 21, 2008, 12:38
Alex Custov, все заработало, большой данке шен за помошь :)
Немного пришлось напильничком обточить, но в общем то что надо :)
Правда не знаю, как с этим делом на маке, но под сузей в КДЕ и гноме пашет.
Что странно - троллевский саппорт ничего дельного так и не предложил...
ИМХО есть смысл таки на вику забросить.

Я их вообще-то не понимаю. Под иксами они используют NETWM вовсю, но именно активацию окна через NETWM не делают. Не понятно.


Название: Re: Bring window to front
Отправлено: Racheengel от Ноябрь 21, 2008, 12:52
Возможно, именно за эту часть у них отвечает какой нибудь индус :)


Название: Re: Bring window to front
Отправлено: Racheengel от Ноябрь 22, 2008, 13:36
Alex, в общем, еще такая проблемка под х11 выползла:
Надо чтобы окно могло динамически менять свое положение между рабочими столами.
То есть либо было видно на всех, либо на одном (текущем).
Делаю так:


Код
C++ (Qt)
void BaseFrame::stickToAll(bool stick)
{
#ifdef Q_WS_X11
   // панель будет видима на всех рабочих столах
   uint val = 0xffffffff;
 
   if (!stick) {
       Atom NET_CURRENT_DESKTOP = XInternAtom(QX11Info::display(), "_NET_CURRENT_DESKTOP", False);
       ulong *u = reinterpret_cast<ulong *>(wm_property(QX11Info::appRootWindow(), NET_CURRENT_DESKTOP, XA_CARDINAL));
       val = (uint)*u;
   }
 
   Atom NET_WM_DESKTOP = XInternAtom(QX11Info::display(), "_NET_WM_DESKTOP", False);
   XChangeProperty(QX11Info::display(), winId(), NET_WM_DESKTOP, XA_CARDINAL, 32,
         PropModeReplace, (unsigned char *)&val, 1);
 
#endif
}

Проблема в том, что функция срабатывает только один раз.
Последующие вызовы  XChangeProperty с другим параметром val ничего не меняют.
В чем может быть баг?


Название: Re: Bring window to front
Отправлено: Alex Custov от Ноябрь 22, 2008, 15:59
чтобы свойства подхватил WM, их нужно менять через сообщения:

Код:
using namespace netwm;

class W : public QPushButton
{
    Q_OBJECT

    public:
        W() : QPushButton("Click")
        {
            netwm::init();
            setCheckable(true);
            connect(this, SIGNAL(toggled(bool)), this, SLOT(slot(bool)));
        }

    public slots:
        void slot(bool stick)
        {
#ifdef Q_WS_X11
            quint32 val = 0xffffffff;

            if(!stick)
            {
                quint32 *u = reinterpret_cast<quint32 *>(::property(QX11Info::appRootWindow(), NET_CURRENT_DESKTOP, XA_CARDINAL, 0));

                if(u)
                {
                    val = (uint) *u;
                    XFree(u);
                }
            }

            qDebug("Setting desktop %d", val);

            climsg(winId(), NET_WM_DESKTOP, val);
#endif
        }
};

Почему ты не пользуешься namespace netwm? Я же специально его добавил, чтобы было удобней.


Название: Re: Bring window to front
Отправлено: pastor от Ноябрь 22, 2008, 16:11
Почему ты не пользуешься namespace netwm? Я же специально его добавил, чтобы было удобней.

Оно то удобней, но если речь идет об *.h файле, то это плохой стиль и не рекомендуеться "показывать" весь namespace в заголовочном файле.


Название: Re: Bring window to front
Отправлено: Alex Custov от Ноябрь 22, 2008, 16:13
Оно то удобней, но если речь идет об *.h файле, то это плохой стиль и не рекомендуеться "показывать" весь namespace в заголовочном файле.

Ик... переведи.


Название: Re: Bring window to front
Отправлено: Rcus от Ноябрь 22, 2008, 16:47
Оно то удобней, но если речь идет об *.h файле, то это плохой стиль и не рекомендуеться "показывать" весь namespace в заголовочном файле.

Ик... переведи.

когда вы включаете заголовочный файл со строкой "using namespace .." в другие файлы то его действие распространяется дальше и может приводить к очень неприятным последствиям сравнимым по действию с неправильно именованными макросами.


Название: Re: Bring window to front
Отправлено: Alex Custov от Ноябрь 22, 2008, 17:14
когда вы включаете заголовочный файл со строкой "using namespace .." в другие файлы то его действие распространяется дальше и может приводить к очень неприятным последствиям сравнимым по действию с неправильно именованными макросами.

"using namespace netwm" используется в .cpp файле, после включения "netwm.h". С чего вы с пастором взяли, что using namespace прописан в .h-ке ? :)


Название: Re: Bring window to front
Отправлено: Racheengel от Ноябрь 22, 2008, 17:17
чтобы свойства подхватил WM, их нужно менять через сообщения:
Почему ты не пользуешься namespace netwm? Я же специально его добавил, чтобы было удобней.

Еще раз благодарю - все заработало :)
Просто я с netwm раньше не работал, некоторые вещи несколько неочевидны и реально требуют опыта...
Насчет namespace я, честно говоря, провтыкал и не скачал твои исходники по ссылке сразу.
А так конечно оно удобнее :)


Название: Re: Bring window to front
Отправлено: Rcus от Ноябрь 22, 2008, 17:19
"using namespace netwm" используется в .cpp файле, после включения "netwm.h". С чего вы с пастором взяли, что using namespace прописан в .h-ке ? :)

А я и не делал предположений. Мой пост пояснял что может быть плохого в абстрактном включении команды using namespace .. в заголовочный файл.


Название: Re: Bring window to front
Отправлено: Alex Custov от Ноябрь 22, 2008, 17:42
А я и не делал предположений. Мой пост пояснял что может быть плохого в абстрактном включении команды using namespace .. в заголовочный файл.

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


Название: Re: Bring window to front
Отправлено: Racheengel от Ноябрь 22, 2008, 17:43
в общем сделал финальный вариант так:

Код:
void BaseFrame::stickToAll(bool stick)
{
#ifdef Q_WS_X11
    // панель будет видима на всех рабочих столах
    uint val = 0xffffffff;

    if (!stick) {
        Atom NET_CURRENT_DESKTOP = XInternAtom(QX11Info::display(), "_NET_CURRENT_DESKTOP", False);
        ulong *u = reinterpret_cast<ulong *>(wm_property(QX11Info::appRootWindow(), NET_CURRENT_DESKTOP, XA_CARDINAL));
        if (u)
            val = (uint)*u;
    }

    Atom NET_WM_DESKTOP = XInternAtom(QX11Info::display(), "_NET_WM_DESKTOP", False);
    wm_climsg(winId(), NET_WM_DESKTOP, val);

    XChangeProperty(QX11Info::display(), winId(), NET_WM_DESKTOP, XA_CARDINAL, 32,
                    PropModeReplace, (unsigned char *)&val, 1);

#endif
}

Причем если  XChangeProperty(...) не оставить, то climsg(...) в первый раз не срабатывает.
Так и должно быть?


Название: Re: Bring window to front
Отправлено: Alex Custov от Ноябрь 22, 2008, 17:46
Просто я с netwm раньше не работал, некоторые вещи несколько неочевидны и реально требуют опыта...

А код установки первоначальных свойств отрабатывал до того, как окно показывалось? Т.е. были ли у тебя какие-то начальные установки свойств ещё до show()?


Название: Re: Bring window to front
Отправлено: Racheengel от Ноябрь 22, 2008, 17:51
До show() у меня netwm нигде не дергается, я все делаю кутишными средствами.
В надежде, что тролли всегда правы :) Но получается, что не всегда...


Название: Re: Bring window to front
Отправлено: Alex Custov от Ноябрь 22, 2008, 18:01
До show() у меня netwm нигде не дергается, я все делаю кутишными средствами.
В надежде, что тролли всегда правы :) Но получается, что не всегда...

Вообще, одного climsg() должно быть достаточно во всех случаях, когда окно уже показано. Одного XChangeProperty() должно быть достаточно только до того как окно показано, потому что оно ещё не управляется оконным менеджером. Надо смотреть весь код, так я не скажу почему так происходит.

Не забывай вызывать XFree. В namespace netwm уже есть атомы, они инициализируются во время init(), постоянно дёргать XInternAtom нехорошо.


Название: Re: Bring window to front
Отправлено: pastor от Ноябрь 22, 2008, 18:04
Оно понятно, что абстрактно. Непонятно как замечание по поводу включения namespace-ов в h-ки могло возникнуть глядя на код выше :)

Очень просто... В коде приведено объявление некого класса  W попрожденного от QPushButton, вверху которого был заюзан namespace netwm. Т.к. в большенстве случаев оъявление класса находиться в заголовочном файле, отсюда и пошло это предположение (прошу заметить, что не утверждение :))