mirror of https://gitee.com/openkylin/riscv.git
!6 修复光标闪烁,配合setting-daemon修复切换CapsLock时丢失焦点
Merge pull request !6 from Renzis/riscv-kwinwayland
This commit is contained in:
commit
88fe1193e0
|
@ -214,6 +214,17 @@ QMatrix4x4 Scene::createProjectionMatrix(const QRect &rect)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void Scene::paintScreen(AbstractOutput *output, const QList<Toplevel *> &toplevels)
|
||||
{
|
||||
createStackingOrder(toplevels);
|
||||
|
||||
const QRect geo = output->geometry();
|
||||
QRegion update = geo, repaint = geo, valid;
|
||||
painted_screen = output;
|
||||
|
||||
paintScreen(geo, repaint, &update, &valid, output->renderLoop(), createProjectionMatrix(output->geometry()));
|
||||
clearStackingOrder();
|
||||
}
|
||||
// returns mask and possibly modified region
|
||||
void Scene::paintScreen(const QRegion &damage, const QRegion &repaint,
|
||||
QRegion *updateRegion, QRegion *validRegion, RenderLoop *renderLoop,
|
||||
|
@ -224,15 +235,66 @@ void Scene::paintScreen(const QRegion &damage, const QRegion &repaint,
|
|||
const std::chrono::milliseconds presentTime =
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(renderLoop->nextPresentationTimestamp());
|
||||
|
||||
if (Q_UNLIKELY(presentTime < m_expectedPresentTimestamp)) {
|
||||
qCDebug(KWIN_CORE,
|
||||
"Provided presentation timestamp is invalid: %lld (current: %lld)",
|
||||
static_cast<long long>(presentTime.count()),
|
||||
static_cast<long long>(m_expectedPresentTimestamp.count()));
|
||||
} else {
|
||||
m_expectedPresentTimestamp = presentTime;
|
||||
}
|
||||
|
||||
// preparation step
|
||||
auto effectsImpl = static_cast<EffectsHandlerImpl *>(effects);
|
||||
effectsImpl->startPaint();
|
||||
|
||||
QRegion region = damage;
|
||||
|
||||
auto screen = painted_screen ? EffectScreenImpl::get(painted_screen) : nullptr;
|
||||
ScreenPrePaintData pdata;
|
||||
pdata.mask = (damage == displayRegion) ? 0 : PAINT_SCREEN_REGION;
|
||||
pdata.paint = region;
|
||||
pdata.screen = screen;
|
||||
|
||||
effects->prePaintScreen(pdata, m_expectedPresentTimestamp);
|
||||
region = pdata.paint;
|
||||
|
||||
int mask = pdata.mask;
|
||||
if (mask & (PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS)) {
|
||||
// Region painting is not possible with transformations,
|
||||
// because screen damage doesn't match transformed positions.
|
||||
mask &= ~PAINT_SCREEN_REGION;
|
||||
region = infiniteRegion();
|
||||
} else if (mask & PAINT_SCREEN_REGION) {
|
||||
// make sure not to go outside visible screen
|
||||
region &= displayRegion;
|
||||
} else {
|
||||
// whole screen, not transformed, force region to be full
|
||||
region = displayRegion;
|
||||
}
|
||||
|
||||
painted_region = region;
|
||||
repaint_region = repaint;
|
||||
|
||||
ScreenPaintData data(projection, screen);
|
||||
effects->paintScreen(mask, region, data);
|
||||
|
||||
Q_EMIT frameRendered();
|
||||
|
||||
for (Window *w : qAsConst(stacking_order)) {
|
||||
effects->postPaintWindow(effectWindow(w));
|
||||
}
|
||||
|
||||
effects->postPaintScreen();
|
||||
|
||||
// make sure not to go outside of the screen area
|
||||
*updateRegion = damaged_region;
|
||||
*validRegion = (region | painted_region) & displayRegion;
|
||||
|
||||
repaint_region = QRegion();
|
||||
damaged_region = QRegion();
|
||||
|
||||
m_paintScreenCount = 0;
|
||||
}
|
||||
|
||||
// the function that'll be eventually called by paintScreen() above
|
||||
|
|
|
@ -81,6 +81,9 @@ public:
|
|||
virtual void paint(AbstractOutput *output, const QRegion &damage, const QList<Toplevel *> &windows,
|
||||
RenderLoop *renderLoop) = 0;
|
||||
|
||||
|
||||
void paintScreen(AbstractOutput *output, const QList<Toplevel *> &toplevels);
|
||||
|
||||
/**
|
||||
* Adds the Toplevel to the Scene.
|
||||
*
|
||||
|
|
|
@ -59,6 +59,75 @@ bool SceneQPainter::initFailed() const
|
|||
return false;
|
||||
}
|
||||
|
||||
void SceneQPainter::paintGenericScreen(int mask, const ScreenPaintData &data)
|
||||
{
|
||||
m_painter->save();
|
||||
m_painter->translate(data.xTranslation(), data.yTranslation());
|
||||
m_painter->scale(data.xScale(), data.yScale());
|
||||
Scene::paintGenericScreen(mask, data);
|
||||
m_painter->restore();
|
||||
}
|
||||
|
||||
void SceneQPainter::paint(AbstractOutput *output, const QRegion &damage, const QList<Toplevel *> &toplevels,
|
||||
RenderLoop *renderLoop)
|
||||
{
|
||||
Q_ASSERT(kwinApp()->platform()->isPerScreenRenderingEnabled());
|
||||
painted_screen = output;
|
||||
|
||||
createStackingOrder(toplevels);
|
||||
|
||||
const QRegion repaint = m_backend->beginFrame(output);
|
||||
const QRect geometry = output->geometry();
|
||||
|
||||
QImage *buffer = m_backend->bufferForScreen(output);
|
||||
if (buffer && !buffer->isNull()) {
|
||||
renderLoop->beginFrame();
|
||||
m_painter->begin(buffer);
|
||||
m_painter->setWindow(geometry);
|
||||
|
||||
QRegion updateRegion, validRegion;
|
||||
|
||||
if (output->useSoftwareCursor()) {
|
||||
paintScreen(damage.intersected(geometry) + Cursors::self()->currentCursor()->geometry(), repaint, &updateRegion, &validRegion, renderLoop);
|
||||
}else{
|
||||
paintScreen(damage.intersected(geometry), repaint, &updateRegion, &validRegion, renderLoop);
|
||||
}
|
||||
paintCursor(output, updateRegion);
|
||||
|
||||
m_painter->end();
|
||||
renderLoop->endFrame();
|
||||
m_backend->endFrame(output, validRegion, updateRegion);
|
||||
}
|
||||
|
||||
// do cleanup
|
||||
clearStackingOrder();
|
||||
}
|
||||
|
||||
void SceneQPainter::paintBackground(const QRegion ®ion)
|
||||
{
|
||||
for (const QRect &rect : region) {
|
||||
m_painter->fillRect(rect, Qt::black);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneQPainter::paintCursor(AbstractOutput *output, const QRegion &rendered)
|
||||
{
|
||||
if (!output || !output->usesSoftwareCursor() || Cursors::self()->isCursorHidden()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Cursor* cursor = Cursors::self()->currentCursor();
|
||||
const QImage img = cursor->image();
|
||||
if (img.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_painter->save();
|
||||
m_painter->setClipRegion(cursor->geometry());
|
||||
m_painter->drawImage(cursor->geometry(), img);
|
||||
m_painter->restore();
|
||||
}
|
||||
|
||||
void SceneQPainter::paintOffscreenQuickView(OffscreenQuickView *w)
|
||||
{
|
||||
QPainter *painter = effects->scenePainter();
|
||||
|
@ -69,6 +138,11 @@ void SceneQPainter::paintOffscreenQuickView(OffscreenQuickView *w)
|
|||
painter->drawImage(w->geometry(), buffer);
|
||||
}
|
||||
|
||||
Scene::Window *SceneQPainter::createWindow(Toplevel *toplevel)
|
||||
{
|
||||
return new SceneQPainter::Window(this, toplevel);
|
||||
}
|
||||
|
||||
Scene::EffectFrame *SceneQPainter::createEffectFrame(EffectFrameImpl *frame)
|
||||
{
|
||||
return new QPainterEffectFrame(frame, this);
|
||||
|
|
|
@ -23,6 +23,8 @@ class KWIN_EXPORT SceneQPainter : public Scene
|
|||
|
||||
public:
|
||||
~SceneQPainter() override;
|
||||
void paint(AbstractOutput *output, const QRegion &damage, const QList<Toplevel *> &windows,
|
||||
RenderLoop *renderLoop) override;
|
||||
void paintGenericScreen(int mask, const ScreenPaintData &data) override;
|
||||
bool initFailed() const override;
|
||||
EffectFrame *createEffectFrame(EffectFrameImpl *frame) override;
|
||||
|
@ -45,6 +47,9 @@ public:
|
|||
static SceneQPainter *createScene(QPainterBackend *backend, QObject *parent);
|
||||
|
||||
protected:
|
||||
void paintBackground(const QRegion ®ion) override;
|
||||
Scene::Window *createWindow(Toplevel *toplevel) override;
|
||||
void paintCursor(AbstractOutput *output, const QRegion ®ion) override;
|
||||
void paintOffscreenQuickView(OffscreenQuickView *w) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -98,6 +98,13 @@ XdgSurfaceClient::~XdgSurfaceClient()
|
|||
qDeleteAll(m_configureEvents);
|
||||
}
|
||||
|
||||
NET::WindowType XdgSurfaceClient::windowType(bool direct, int supported_types) const
|
||||
{
|
||||
Q_UNUSED(direct)
|
||||
Q_UNUSED(supported_types)
|
||||
return m_windowType;
|
||||
}
|
||||
|
||||
QRect XdgSurfaceClient::inputGeometry() const
|
||||
{
|
||||
return isDecorated() ? AbstractClient::inputGeometry() : bufferGeometry();
|
||||
|
@ -1021,9 +1028,58 @@ void XdgToplevelClient::doFinishInteractiveMoveResize()
|
|||
|
||||
bool XdgToplevelClient::takeFocus()
|
||||
{
|
||||
if (this->caption().contains("sogou", Qt::CaseInsensitive))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (wantsInput()) {
|
||||
sendPing(PingReason::FocusWindow);
|
||||
setActive(true);
|
||||
}
|
||||
|
||||
if (workspace()->showingDesktop() && !keepAbove() && !isOnScreenDisplay() && !belongsToDesktop()) {
|
||||
for (auto c : workspace()->allClientList()) {
|
||||
if ( this == c || c->isDock() || c->isDesktop() || c->skipTaskbar()) {
|
||||
continue;
|
||||
} else {
|
||||
c->minimize(true);
|
||||
}
|
||||
}
|
||||
workspace()->setShowingDesktop(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool XdgToplevelClient::wantsInput() const
|
||||
{
|
||||
return rules()->checkAcceptFocus(acceptsFocus());
|
||||
}
|
||||
|
||||
bool XdgToplevelClient::dockWantsInput() const
|
||||
{
|
||||
if (m_plasmaShellSurface) {
|
||||
if (m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::Panel) {
|
||||
return m_plasmaShellSurface->panelTakesFocus();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool XdgToplevelClient::acceptsFocus() const
|
||||
{
|
||||
if (m_plasmaShellSurface) {
|
||||
if (m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::OnScreenDisplay ||
|
||||
m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::ToolTip) {
|
||||
return false;
|
||||
}
|
||||
if (m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::Notification ||
|
||||
m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::CriticalNotification) {
|
||||
return m_plasmaShellSurface->panelTakesFocus();
|
||||
}
|
||||
}
|
||||
return !isZombie() && readyForPainting();
|
||||
}
|
||||
|
||||
Layer XdgToplevelClient::layerForDock() const
|
||||
{
|
||||
if (m_plasmaShellSurface) {
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
explicit XdgSurfaceClient(KWaylandServer::XdgSurfaceInterface *shellSurface);
|
||||
~XdgSurfaceClient() override;
|
||||
|
||||
NET::WindowType windowType(bool direct = false, int supported_types = 0) const override;
|
||||
QRect frameRectToBufferRect(const QRect &rect) const override;
|
||||
QRect inputGeometry() const override;
|
||||
QMatrix4x4 inputTransformation() const override;
|
||||
|
|
Loading…
Reference in New Issue