TQDesktopWidget: backport changes from Qt4

The class was little changed during lifetime of Qt4, so it was possible
to relatively easy backport them. This changeset is based on Qt4.8.7.

The changes include:

* This fixes several issues on "old-school multihead" X11 setups (with
  several screens per display i.e. when DISPLAY has form ":x.y" also
  known as "TDE_MULTIHEAD" or "Zaphod mode"). In particular:
  * fix graphical drag&drop problems across displays.
  * fix menus being displayed outside of the screen.
* add screenCountChanged() signal
* emit resized() signal

See-also: https://github.com/qt/qt/blob/v4.8.7/src/gui/kernel/qdesktopwidget_x11.cpp
Signed-off-by: Alexander Golubev <fatzer2@gmail.com>
Fat-Zer/fix/tqdesktopwidget
Alexander Golubev 5 days ago
parent 58fc40e34a
commit 2da86558cc

@ -82,6 +82,7 @@ public:
signals:
void resized( int );
void workAreaResized( int );
void screenCountChanged( int );
protected:
void resizeEvent( TQResizeEvent *e );

@ -39,6 +39,7 @@
#include "tqdesktopwidget.h"
#include "tqapplication.h"
#include "tqobjectlist.h"
#include "tqvaluevector.h"
#include "tqt_x11_p.h"
#include <cstdlib>
@ -56,7 +57,6 @@ void tqt_desktopwidget_update_workarea()
tqt_desktopwidget_workarea_dirty = true;
}
class TQSingleDesktopWidget : public TQWidget
{
public:
@ -118,14 +118,19 @@ TQDesktopWidgetPrivate::~TQDesktopWidgetPrivate()
void TQDesktopWidgetPrivate::init()
{
// get the screen count
int newScreenCount;
int newScreenCount = ScreenCount(TQPaintDevice::x11AppDisplay());
#ifndef TQT_NO_XINERAMA
XineramaScreenInfo *xinerama_screeninfo = 0;
int unused;
use_xinerama = (XineramaQueryExtension(TQPaintDevice::x11AppDisplay(),
&unused, &unused) &&
XineramaIsActive(TQPaintDevice::x11AppDisplay()));
// we ignore the Xinerama extension when the display is using
// traditional multi-screen (with multiple root windows)
if (newScreenCount == 1) {
int unused;
use_xinerama = ( XineramaQueryExtension(TQPaintDevice::x11AppDisplay(),
&unused, &unused)
&& XineramaIsActive(TQPaintDevice::x11AppDisplay()));
}
if (use_xinerama) {
xinerama_screeninfo =
@ -148,7 +153,7 @@ void TQDesktopWidgetPrivate::init()
// get the geometry of each screen
int i, j, x, y, w, h;
for ( i = 0, j = 0; i < newScreenCount; i++ ) {
for (i = 0, j = 0; i < newScreenCount; i++, j++) {
#ifndef TQT_NO_XINERAMA
if (use_xinerama) {
@ -165,18 +170,18 @@ void TQDesktopWidgetPrivate::init()
h = HeightOfScreen(ScreenOfDisplay(TQPaintDevice::x11AppDisplay(), i));
}
workareas[i] = TQRect();
rects[j].setRect(x, y, w, h);
// overlapping?
if (j > 0 && rects[j-1].intersects(rects[j])) {
// pick the bigger one, ignore the other
if (use_xinerama && j > 0 && rects[j-1].intersects(rects[j])) {
// merge a "cloned" screen with the previous, hiding all crtcs
// that are currently showing a sub-rect of the previous screen
if ((rects[j].width()*rects[j].height()) >
(rects[j-1].width()*rects[j-1].height()))
rects[j-1] = rects[j];
rects[j-1] = rects[j];
j--;
}
else
j++;
workareas[i] = TQRect();
}
if (screens) {
@ -274,26 +279,37 @@ const TQRect& TQDesktopWidget::availableGeometry( int screen ) const
if ( d->workareas[screen].isValid() )
return d->workareas[screen];
if ( ! isVirtualDesktop() && tqt_net_supports( tqt_net_workarea ) ) {
if ( tqt_net_supports( tqt_net_workarea ) ) {
int x11Screen = isVirtualDesktop() ?
DefaultScreen(TQPaintDevice::x11AppDisplay()) : screen;
Atom ret;
int format, e;
unsigned char *data = 0;
unsigned long nitems, after;
e = XGetWindowProperty( TQPaintDevice::x11AppDisplay(),
TQPaintDevice::x11AppRootWindow( screen ),
TQPaintDevice::x11AppRootWindow( x11Screen ),
tqt_net_workarea, 0, 4, False, XA_CARDINAL,
&ret, &format, &nitems, &after, &data );
TQRect workArea;
if ( e == Success && ret == XA_CARDINAL &&
format == 32 && nitems == 4
) {
long *workarea = (long *) data;
d->workareas[screen].setRect( workarea[0], workarea[1],
workarea[2], workarea[3] );
workArea = TQRect(workarea[0], workarea[1], workarea[2], workarea[3]);
} else {
d->workareas[screen] = screenGeometry(screen);
workArea = screenGeometry(screen);
}
if (isVirtualDesktop()) {
// intersect the workarea (which spawns all Xinerama screens) with the rect for the
// requested screen
workArea &= screenGeometry(screen);
}
d->workareas[screen] = workArea;
if ( data )
XFree( data );
} else {
@ -352,6 +368,23 @@ int TQDesktopWidget::screenNumber( const TQPoint &point ) const
void TQDesktopWidget::resizeEvent( TQResizeEvent *event )
{
int oldScreenCount = d->screenCount;
TQValueVector<TQRect> oldRects(oldScreenCount);
for (int i = 0; i < oldScreenCount; ++i) {
oldRects[i] = d->rects[i];
}
d->init();
for (int i = 0; i < TQMIN(oldScreenCount, d->screenCount); ++i) {
if (oldRects.at(i) != d->rects[i])
emit resized(i);
}
if (oldScreenCount != d->screenCount) {
emit screenCountChanged(d->screenCount);
}
d->init();
tqt_desktopwidget_workarea_dirty = true;
TQWidget::resizeEvent( event );

Loading…
Cancel
Save