JoseExposito / eggwm

Automatically exported from code.google.com/p/eggwm
3 stars 1 forks source link

razorqt panel crash: NET_WM_DESKTOP data are 0x0 #6

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
I'm testing eggwm with razorqt environment.

I receive crashes of panel when there is at least one window opened. It looks 
like the NET_WM_DESKTOP window property is not initialized correctly in eggwm - 
it's always 0x0

I introduced small and hacky workaround:

int XfitMan::getWindowDesktop(Window _wid)
{
    int  format;
    unsigned long type, length, rest, *data;
    //so we try to use net_wm_desktop first, but if the system does not use net_wm standard we use win_workspace!
    if (XGetWindowProperty(QX11Info::display(),_wid,atomMap["net_wm_desktop"],0, 4096, FALSE, XA_CARDINAL,
                           &type, &format, &length, &rest,(unsigned char**) &data) != Success)
    {
        qDebug() << "XfitMan::getWindowDesktop() NET_WM_DESKTOP is not set ("<<atomMap["net_wm_desktop"]<<")";
        if (XGetWindowProperty(QX11Info::display(),_wid,atomMap["_win_workspace"],0, 4096, FALSE, XA_CARDINAL,
                           &type, &format, &length, &rest,(unsigned char**) &data) != Success)
        {
            qDebug() << "XfitMan::getWindowDesktop() FAILBACK: Window" << _wid << "does not have set NET_WM_DESKTOP ("<<atomMap["net_wm_desktop"]<<") or _WIN_WORKSPACE (" <<atomMap["_win_workspace"]<<")";
            return -1;
        }
    }
    qDebug() << "XfitMan::getWindowDesktop() desktop should be known";
    //
    // HACK: eggwm does not initialize data in this case. But it shoul (?) because all other WMs do it...
    //
    if (!data)
    {
        qDebug() << "XfitMan::getWindowDesktop() WARNING *data is empty (uninitialized). And it's wrong!";
        return -1;
    }
    int desktop = data[0];
    XFree(data);
    return desktop;
}

Original issue reported on code.google.com by yarpe...@gmail.com on 27 Jan 2011 at 7:29

GoogleCodeExporter commented 9 years ago
Hi, check EWMHRoot.cpp line 190:

void EWMHRoot::sendDesktopNames(const QString& name) const {
    // TODO Don't works fine!!
    const char* charName = name.toUtf8().constData() + '\0';

    XChangeProperty(QX11Info::display(),
            QX11Info::appRootWindow(QX11Info::appScreen()),
            al->getAtom("_NET_DESKTOP_NAMES"),
            al->getAtom("UTF8_STRING"),
            8, PropModeReplace,
            (const unsigned char*)&charName,
            name.length()+1);
}

I need to sent a real UTF8_STRING, but I can't... some idea/code?

Original comment by jose.exposito89@gmail.com on 27 Jan 2011 at 11:29

GoogleCodeExporter commented 9 years ago
in qt4 qwidget's implementation they use:

QByteArray net_wm_name = caption.toUtf8();
XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_NAME), 
ATOM(UTF8_STRING), 8,
                                PropModeReplace, (unsigned char *)net_wm_name.data(), net_wm_name.size());

Original comment by yarpe...@gmail.com on 27 Jan 2011 at 11:39

GoogleCodeExporter commented 9 years ago
What object is "caption" in your code?

Original comment by jose.exposito89@gmail.com on 27 Jan 2011 at 11:49

GoogleCodeExporter commented 9 years ago
it's a snippet only. It looks like they just use QByteArray instead of const 
char*. It should be the same, but this one works. Maybe there is something with 
constData() in your code. Dunno.

void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
{

    Q_Q(QWidget);

    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
    if (!q->internalWinId())
        return;
    XSetWMName(X11->display, q->internalWinId(), qstring_to_xtp(caption));

    QByteArray net_wm_name = caption.toUtf8();
    XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_NAME), ATOM(UTF8_STRING), 8,
                    PropModeReplace, (unsigned char *)net_wm_name.data(), net_wm_name.size());

}

Original comment by yarpe...@gmail.com on 27 Jan 2011 at 12:29

GoogleCodeExporter commented 9 years ago
Ok solved:

void EWMHRoot::sendDesktopNames(const QString& name) const {
    QWidget w;
    w.setWindowTitle(name);
    QByteArray desktopName = w.windowTitle().toUtf8();

    XChangeProperty(QX11Info::display(),
            QX11Info::appRootWindow(QX11Info::appScreen()),
            al->getAtom("_NET_DESKTOP_NAMES"),
            al->getAtom("UTF8_STRING"),
            8, PropModeReplace,
            (const unsigned char*)desktopName.data(),
            desktopName.size());
}

Is a really nasty hack.. but works...

For next version will be avalible ;)
Thanks!!!!

Original comment by jose.exposito89@gmail.com on 27 Jan 2011 at 12:39

GoogleCodeExporter commented 9 years ago
where I can test it, please? Trunk's last change is from Jan 16, 2011.

Original comment by yarpe...@gmail.com on 27 Jan 2011 at 12:57

GoogleCodeExporter commented 9 years ago
Updated ;)

Original comment by jose.exposito89@gmail.com on 27 Jan 2011 at 1:11