~ci-train-bot/qtubuntu/qtubuntu-ubuntu-xenial-landing-005

« back to all changes in this revision

Viewing changes to src/ubuntumirclient/input.cpp

  • Committer: CI Train Bot
  • Author(s): Alberto Aguirre
  • Date: 2015-11-17 14:49:21 UTC
  • mfrom: (258.6.46 use-mir-surface-apis)
  • Revision ID: ci-train-bot@canonical.com-20151117144921-nrpn5zal5ncrjxvt
Add support for Qt popups and dialog windows.

I have done some refactoring, cleanup and some bug fixing.

- An UbuntuWindow internally creates UbuntuSurface
- UbuntuSurface is responsible for creating the mir surfaces and calling mir apis
- Fix mutex locking (now really protecting access to mSurface) was not locked properly (QMutexLocker temporaries were created : QMutexLocker(&d->mutex) instead of QMutexLocker lock(&d->mutex).
- Handling resize events from the server has been improved.
-- Old resize events are dropped - meaning no redraw requests are issued if we know there are newer resize events in the queue
-- Redraw requests are never issued through the rendering thread only through the Qt event dispatch thread.
-- No flushing of event queue which leads to fewer interruptions in other surfaces (specially noticeable on surfaces that do animations).
- Workaround QtCreator not assigning a parent to its menu bar menus
-- The last focused window is tracked and used if a Qt popup is created without a parent
- Client requested resizes (through setGeometry) is now supported
- Resizing constraints are supported (propagateSizeHints)
- Visibility and window state are tracked separately
- Better focusing event handling
-- When an app has multiple windows, mir will send focus lost/gain pairs,
   in which case we need to peek into the queue to avoid telling Qt to unfocus all windows prematurely.
Approved by: PS Jenkins bot, Daniel d'Andrada

Show diffs side-by-side

added added

removed removed

Lines of Context:
142
142
    , mEventFilterType(static_cast<UbuntuNativeInterface*>(
143
143
        integration->nativeInterface())->genericEventFilterType())
144
144
    , mEventType(static_cast<QEvent::Type>(QEvent::registerEventType()))
 
145
    , mLastFocusedWindow(nullptr)
145
146
{
146
147
    // Initialize touch device.
147
148
    mTouchDevice = new QTouchDevice;
213
214
    switch (mir_event_get_type(nativeEvent))
214
215
    {
215
216
    case mir_event_type_input:
216
 
        dispatchInputEvent(ubuntuEvent->window->window(), mir_event_get_input_event(nativeEvent));
 
217
        dispatchInputEvent(ubuntuEvent->window, mir_event_get_input_event(nativeEvent));
217
218
        break;
218
219
    case mir_event_type_resize:
219
220
    {
225
226
                mir_resize_event_get_width(resizeEvent),
226
227
                mir_resize_event_get_height(resizeEvent));
227
228
 
228
 
        ubuntuEvent->window->handleSurfaceResize(mir_resize_event_get_width(resizeEvent),
 
229
        ubuntuEvent->window->handleSurfaceResized(mir_resize_event_get_width(resizeEvent),
229
230
            mir_resize_event_get_height(resizeEvent));
230
231
        break;
231
232
    }
233
234
    {
234
235
        auto surfaceEvent = mir_event_get_surface_event(nativeEvent);
235
236
        if (mir_surface_event_get_attribute(surfaceEvent) == mir_surface_attrib_focus) {
236
 
            ubuntuEvent->window->handleSurfaceFocusChange(mir_surface_event_get_attribute_value(surfaceEvent) ==
237
 
                mir_surface_focused);
 
237
            const bool focused = mir_surface_event_get_attribute_value(surfaceEvent) == mir_surface_focused;
 
238
            // Mir may have sent a pair of focus lost/gained events, so we need to "peek" into the queue
 
239
            // so that we don't deactivate windows prematurely.
 
240
            if (focused) {
 
241
                mPendingFocusGainedEvents--;
 
242
                ubuntuEvent->window->handleSurfaceFocused();
 
243
            } else if(!mPendingFocusGainedEvents) {
 
244
                DLOG("[ubuntumirclient QPA] No windows have focus");
 
245
                QWindowSystemInterface::handleWindowActivated(nullptr, Qt::ActiveWindowFocusReason);
 
246
            }
238
247
        }
239
248
        break;
240
249
    }
253
262
{
254
263
    QWindow *window = platformWindow->window();
255
264
 
 
265
    const auto eventType = mir_event_get_type(event);
 
266
    if (mir_event_type_surface == eventType) {
 
267
        auto surfaceEvent = mir_event_get_surface_event(event);
 
268
        if (mir_surface_attrib_focus == mir_surface_event_get_attribute(surfaceEvent)) {
 
269
            const bool focused = mir_surface_event_get_attribute_value(surfaceEvent) == mir_surface_focused;
 
270
            if (focused) {
 
271
                mPendingFocusGainedEvents++;
 
272
            }
 
273
        }
 
274
    }
 
275
 
256
276
    QCoreApplication::postEvent(this, new UbuntuEvent(
257
277
            platformWindow, event, mEventType));
258
278
 
263
283
    }
264
284
}
265
285
 
266
 
void UbuntuInput::dispatchInputEvent(QWindow *window, const MirInputEvent *ev)
 
286
void UbuntuInput::dispatchInputEvent(UbuntuWindow *window, const MirInputEvent *ev)
267
287
{
268
288
    switch (mir_input_event_get_type(ev))
269
289
    {
281
301
    }
282
302
}
283
303
 
284
 
void UbuntuInput::dispatchTouchEvent(QWindow *window, const MirInputEvent *ev)
 
304
void UbuntuInput::dispatchTouchEvent(UbuntuWindow *window, const MirInputEvent *ev)
285
305
{
286
306
    const MirTouchEvent *tev = mir_input_event_get_touch_event(ev);
287
307
 
312
332
        switch (touch_action)
313
333
        {
314
334
        case mir_touch_action_down:
 
335
            mLastFocusedWindow = window;
315
336
            touchPoint.state = Qt::TouchPointPressed;
316
337
            break;
317
338
        case mir_touch_action_up:
326
347
    }
327
348
 
328
349
    ulong timestamp = mir_input_event_get_event_time(ev) / 1000000;
329
 
    QWindowSystemInterface::handleTouchEvent(window, timestamp,
 
350
    QWindowSystemInterface::handleTouchEvent(window->window(), timestamp,
330
351
            mTouchDevice, touchPoints);
331
352
}
332
353
 
369
390
}
370
391
}
371
392
 
372
 
void UbuntuInput::dispatchKeyEvent(QWindow *window, const MirInputEvent *event)
 
393
void UbuntuInput::dispatchKeyEvent(UbuntuWindow *window, const MirInputEvent *event)
373
394
{
374
395
    const MirKeyboardEvent *key_event = mir_input_event_get_keyboard_event(event);
375
396
 
383
404
    QEvent::Type keyType = action == mir_keyboard_action_up
384
405
        ? QEvent::KeyRelease : QEvent::KeyPress;
385
406
 
 
407
    if (action == mir_keyboard_action_down)
 
408
        mLastFocusedWindow = window;
 
409
 
386
410
    char s[2];
387
411
    int sym = translateKeysym(xk_sym, s, sizeof(s));
388
412
    QString text = QString::fromLatin1(s);
399
423
        }
400
424
    }
401
425
 
402
 
    QWindowSystemInterface::handleKeyEvent(window, timestamp, keyType, sym, modifiers, text, is_auto_rep);
 
426
    QWindowSystemInterface::handleKeyEvent(window->window(), timestamp, keyType, sym, modifiers, text, is_auto_rep);
403
427
}
404
428
 
405
429
namespace
422
446
}
423
447
}
424
448
 
425
 
void UbuntuInput::dispatchPointerEvent(QWindow *window, const MirInputEvent *ev)
 
449
void UbuntuInput::dispatchPointerEvent(UbuntuWindow *platformWindow, const MirInputEvent *ev)
426
450
{
 
451
    auto window = platformWindow->window();
427
452
    auto timestamp = mir_input_event_get_event_time(ev) / 1000000;
428
453
 
429
454
    auto pev = mir_input_event_get_pointer_event(ev);
446
471
                                                     QPoint(), angleDelta, modifiers, Qt::ScrollUpdate);
447
472
        } else {
448
473
            auto buttons = extract_buttons(pev);
 
474
            if (buttons != Qt::NoButton)
 
475
                mLastFocusedWindow = platformWindow;
449
476
            QWindowSystemInterface::handleMouseEvent(window, timestamp, localPoint, localPoint /* Should we omit global point instead? */,
450
477
                                                     buttons, modifiers);
451
478
        }