~unity-2d-team/unity-2d/shortcut-hint-overlay

« back to all changes in this revision

Viewing changes to libunity-2d-private/src/unity2ddeclarativeview.cpp

  • Committer: Tiago Salem Herrmann
  • Date: 2012-03-19 15:28:41 UTC
  • mfrom: (771.40.182 unity-2d)
  • Revision ID: tiago.herrmann@canonical.com-20120319152841-2hfflo67muks7gca
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
#include "screeninfo.h"
23
23
 
 
24
#include <QApplication>
24
25
#include <QDebug>
 
26
#include <QDeclarativeEngine>
 
27
#include <QDeclarativeItem>
25
28
#include <QGLWidget>
26
29
#include <QVariant>
27
30
#include <QX11Info>
31
34
#include <X11/Xlib.h>
32
35
#include <X11/Xatom.h>
33
36
 
34
 
// libwnck
35
 
extern "C" {
36
 
#include <libwnck/libwnck.h>
37
 
}
38
 
 
39
 
#define GOBJECT_CALLBACK0(callbackName, slot) \
40
 
static void \
41
 
callbackName(GObject* src, void* dummy1, QObject* dst) \
42
 
{ \
43
 
    QMetaObject::invokeMethod(dst, slot); \
44
 
}
45
 
 
46
 
GOBJECT_CALLBACK0(activeWorkspaceChangedCB, "onActiveWorkspaceChanged");
47
 
 
48
37
Unity2DDeclarativeView::Unity2DDeclarativeView(QWidget *parent) :
49
 
    QDeclarativeView(parent),
 
38
    QGraphicsView(parent),
50
39
    m_screenInfo(NULL),
51
40
    m_useOpenGL(false),
52
41
    m_transparentBackground(false),
53
 
    m_last_focused_window(None)
 
42
    m_rootItem(NULL)
54
43
{
 
44
    setScene(&m_scene);
 
45
 
 
46
    setOptimizationFlags(QGraphicsView::DontSavePainterState);
 
47
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
 
48
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
 
49
    setFrameStyle(NoFrame);
 
50
 
 
51
    setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
 
52
    scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
 
53
    viewport()->setFocusPolicy(Qt::NoFocus);
 
54
    setFocusPolicy(Qt::StrongFocus);
 
55
 
 
56
    scene()->setStickyFocus(true);
 
57
 
55
58
    if (!QFileInfo(UNITY_2D_SCHEMA_FILE).exists()) {
56
59
        m_useOpenGL = false;
57
60
    } else {
58
61
        m_useOpenGL = unity2dConfiguration().property("useOpengl").toBool();
59
62
    }
60
63
 
61
 
    WnckScreen* screen = wnck_screen_get_default();
62
 
    g_signal_connect(G_OBJECT(screen), "active_workspace_changed", G_CALLBACK(activeWorkspaceChangedCB), this);
63
 
 
64
64
    setupViewport();
65
65
}
66
66
 
68
68
{
69
69
}
70
70
 
 
71
QDeclarativeEngine* Unity2DDeclarativeView::engine()
 
72
{
 
73
    static QDeclarativeEngine* engine = new QDeclarativeEngine();
 
74
    return engine;
 
75
}
 
76
 
 
77
QDeclarativeContext* Unity2DDeclarativeView::rootContext() const
 
78
{
 
79
    return engine()->rootContext();
 
80
}
 
81
 
 
82
QDeclarativeItem* Unity2DDeclarativeView::rootObject() const
 
83
{
 
84
    return m_rootItem;
 
85
}
 
86
 
 
87
void Unity2DDeclarativeView::forceActivateWindow()
 
88
{
 
89
    forceActivateWindow(effectiveWinId(), this);
 
90
}
 
91
 
 
92
void Unity2DDeclarativeView::setSource(const QUrl &source, const QMap<const char*, QVariant> &rootObjectProperties)
 
93
{
 
94
    QDeclarativeComponent* component = new QDeclarativeComponent(engine(), source, this);
 
95
    QObject *instance = component->beginCreate(rootContext());
 
96
    if (component->isError()) {
 
97
        qDebug() << component->errors();
 
98
    }
 
99
    QMap<const char*, QVariant>::const_iterator it = rootObjectProperties.begin();
 
100
    QMap<const char*, QVariant>::const_iterator itEnd = rootObjectProperties.end();
 
101
    for ( ; it != itEnd; ++it) {
 
102
        instance->setProperty(it.key(), it.value());
 
103
    }
 
104
    component->completeCreate();
 
105
    m_rootItem = qobject_cast<QDeclarativeItem *>(instance);
 
106
    connect(m_rootItem, SIGNAL(widthChanged()), SLOT(resizeToRootObject()));
 
107
    connect(m_rootItem, SIGNAL(heightChanged()), SLOT(resizeToRootObject()));
 
108
    resizeToRootObject();
 
109
    m_scene.addItem(m_rootItem);
 
110
    m_source = source;
 
111
}
 
112
 
 
113
void Unity2DDeclarativeView::resizeToRootObject()
 
114
{
 
115
    QSize size(m_rootItem->width(), m_rootItem->height());
 
116
    resize(size);
 
117
    setSceneRect(QRectF(0, 0, size.width(), size.height()));
 
118
    Q_EMIT sceneResized(size);
 
119
}
 
120
 
71
121
bool Unity2DDeclarativeView::useOpenGL() const
72
122
{
73
123
    return m_useOpenGL;
90
140
    return m_transparentBackground;
91
141
}
92
142
 
 
143
QUrl Unity2DDeclarativeView::source() const
 
144
{
 
145
    return m_source;
 
146
}
 
147
 
93
148
void Unity2DDeclarativeView::setTransparentBackground(bool transparentBackground)
94
149
{
95
150
    if (transparentBackground == m_transparentBackground) {
104
159
 
105
160
QPoint Unity2DDeclarativeView::globalPosition() const
106
161
{
107
 
    return mapToGlobal(QPoint(0,0));
 
162
    // FIXME This used to be mapToGlobal(QPoint(0,0)) that is the correct
 
163
    // thing for all kind of widgets, but seems to fail sometimes if we
 
164
    // call it just after a moveEvent, which is bad
 
165
    // Since all our Unity2DDeclarativeView are toplevel windows we
 
166
    // are workarounding it by just returning pos()
 
167
    return pos();
108
168
}
109
169
 
110
170
void Unity2DDeclarativeView::setupViewport()
164
224
 
165
225
void Unity2DDeclarativeView::showEvent(QShowEvent* event)
166
226
{
167
 
    QDeclarativeView::showEvent(event);
 
227
    QGraphicsView::showEvent(event);
168
228
    Q_EMIT visibleChanged(true);
169
229
}
170
230
 
171
231
void Unity2DDeclarativeView::hideEvent(QHideEvent* event)
172
232
{
173
 
    QDeclarativeView::hideEvent(event);
 
233
    QGraphicsView::hideEvent(event);
174
234
    Q_EMIT visibleChanged(false);
175
235
}
176
236
 
177
 
/* Obtaining & Discarding Keyboard Focus for Window on Demand
178
 
 *
179
 
 * In the X world, activating a window means to give it the input (keyboard)
180
 
 * focus. When a new window opens, X usually makes it active immediately.
181
 
 * Clicking on a window makes it active too.
182
 
 *
183
 
 * Qt does not have the capability to explicitly ask the window manager to
184
 
 * make an existing window active - setFocus() only forwards input focus to
185
 
 * whatever QWidget you specify.
186
 
 *
187
 
 * De-Activating a window is not possible with X (and hence with Qt). So
188
 
 * we work-around this by remembering which application is active prior to
189
 
 * stealing focus, and then Re-Activating it when we're finished. This is
190
 
 * not guaranteed to succeed, as previous window may have closed.
191
 
 *
192
 
 * The following methods deal with these tasks. Note that when the window
193
 
 * has been activated (deactivated), Qt will realise it has obtained (lost)
194
 
 * focus and act appropriately.
195
 
 */
196
 
 
197
 
/* Ask Window Manager to activate this window and hence get keyboard focus */
198
 
void Unity2DDeclarativeView::forceActivateWindow()
199
 
{
200
 
    // Save reference to window with current keyboard focus
201
 
    if( m_last_focused_window == None ){
202
 
        saveActiveWindow();
203
 
    }
204
 
 
205
 
    // Show this window by giving it keyboard focus
206
 
    forceActivateThisWindow(this->effectiveWinId());
207
 
}
208
 
 
209
 
/* Ask Window Manager to deactivate this window - not guaranteed to succeed. */
210
 
void Unity2DDeclarativeView::forceDeactivateWindow()
211
 
{
212
 
    if( m_last_focused_window == None ){
213
 
        UQ_WARNING << "No previously focused window found, use mouse to select window.";
214
 
        return;
215
 
    }
216
 
 
217
 
    // What if previously focused window closed while we we had focus? Check if window
218
 
    // exists by seeing if it has attributes.
219
 
    int status;
220
 
    XWindowAttributes attributes;
221
 
    status = XGetWindowAttributes(QX11Info::display(), m_last_focused_window, &attributes);
222
 
    if ( status == BadWindow ){
223
 
        UQ_WARNING << "Previously focused window has gone, use mouse to select window.";
224
 
        return;
225
 
    }
226
 
 
227
 
    // Show this window by giving it keyboard focus
228
 
    forceActivateThisWindow(m_last_focused_window);
229
 
 
230
 
    m_last_focused_window = None;
231
 
}
232
 
 
233
 
void Unity2DDeclarativeView::forceActivateThisWindow(WId window)
 
237
void Unity2DDeclarativeView::keyPressEvent(QKeyEvent* event)
 
238
{
 
239
    QApplication::sendEvent(scene(), event);
 
240
}
 
241
 
 
242
void Unity2DDeclarativeView::keyReleaseEvent(QKeyEvent* event)
 
243
{
 
244
    QApplication::sendEvent(scene(), event);
 
245
}
 
246
 
 
247
void Unity2DDeclarativeView::forceActivateWindow(WId window, QWidget *w)
234
248
{
235
249
    /* Workaround focus stealing prevention implemented by some window
236
250
       managers such as Compiz. This is the exact same code you will find in
262
276
    XFlush(display);
263
277
 
264
278
    /* Use Qt's setFocus mechanism as a safety guard in case the above failed */
265
 
    setFocus();
266
 
}
267
 
 
268
 
/* Save WId of window with keyboard focus to m_last_focused_window */
269
 
void Unity2DDeclarativeView::saveActiveWindow()
270
 
{
271
 
    Display* display = QX11Info::display();
272
 
    WId active_window;
273
 
    int current_focus_state;
274
 
 
275
 
    XGetInputFocus(display, &active_window, &current_focus_state);
276
 
    if( active_window != this->effectiveWinId()){
277
 
        m_last_focused_window = active_window;
278
 
    }
279
 
}
280
 
 
281
 
void Unity2DDeclarativeView::onActiveWorkspaceChanged() 
282
 
{
283
 
    m_last_focused_window = None;
284
 
    Q_EMIT activeWorkspaceChanged();
 
279
    if (w != NULL)
 
280
        w->setFocus();
285
281
}
286
282
 
287
283
ScreenInfo*