!6 修复光标闪烁,配合setting-daemon修复切换CapsLock时丢失焦点

Merge pull request !6 from Renzis/riscv-kwinwayland
This commit is contained in:
李卓珩 2023-10-08 01:26:37 +00:00 committed by Gitee
commit 88fe1193e0
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 201 additions and 0 deletions

View File

@ -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

View File

@ -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.
*

View File

@ -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 &region)
{
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);

View File

@ -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 &region) override;
Scene::Window *createWindow(Toplevel *toplevel) override;
void paintCursor(AbstractOutput *output, const QRegion &region) override;
void paintOffscreenQuickView(OffscreenQuickView *w) override;
private:

View File

@ -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) {

View File

@ -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;