Commit 7637cfc2 authored by Vlad Zahorodnii's avatar Vlad Zahorodnii

[scenes/opengl] Fix overlapping shadow tiles

Summary:
This problem appears if shadow corner tiles are too big and
some window has size smaller than 2 * shadowTileSize.

This change tries to address the problem above by exclusing
overlapping tile parts. If there are any two overlapping corners
then tile between them(top/right/bottom/left) is not rendered.

Also, because some corner tile parts can be excluded, corner tiles
are expected to be symmetrical(i.e. if we remove right half from
the top-left tile and left half from the top-right tile and
stick them together, they still look fine, there are no misalignments, etc).
Most shadows(e.g. shadows from Breeze) have such behaviour.

No tiles are overlapping

{F5728514, layout=center, size=full}

Overlapping tiles

{F5728516, layout=center, size=full}

And this is how it supposed to be

{F5728517, layout=center, size=full}

Test Plan:
* apply D11069 to Breeze
* in System Settings/Application Style/Window Decorations, choose "Very Large" shadow size
* open Konsole
* resize it to a minimum possible size

Reviewers: #kwin, graesslin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: davidedmundson, ngraham, anemeth, abetts, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D10811
parent a3cff85e
......@@ -39,6 +39,7 @@ integrationTest(WAYLAND_ONLY NAME testShellClient SRCS shell_client_test.cpp)
integrationTest(WAYLAND_ONLY NAME testDontCrashNoBorder SRCS dont_crash_no_border.cpp)
integrationTest(NAME testXClipboardSync SRCS xclipboardsync_test.cpp)
integrationTest(WAYLAND_ONLY NAME testSceneOpenGL SRCS scene_opengl_test.cpp generic_scene_opengl_test.cpp)
integrationTest(WAYLAND_ONLY NAME testSceneOpenGLShadow SRCS scene_opengl_shadow_test.cpp)
integrationTest(WAYLAND_ONLY NAME testSceneOpenGLES SRCS scene_opengl_es_test.cpp generic_scene_opengl_test.cpp)
integrationTest(WAYLAND_ONLY NAME testNoXdgRuntimeDir SRCS no_xdg_runtime_dir_test.cpp)
integrationTest(WAYLAND_ONLY NAME testScreenChanges SRCS screen_changes_test.cpp)
......@@ -79,3 +80,4 @@ endif()
add_subdirectory(scripting)
add_subdirectory(effects)
add_subdirectory(fakes)
add_subdirectory(org.kde.kdecoration2)
########################################################
# FakeDecoWithShadows
########################################################
add_library(fakedecoshadows MODULE fakedecoration_with_shadows.cpp)
set_target_properties(fakedecoshadows PROPERTIES
PREFIX ""
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/fakes/org.kde.kdecoration2")
target_link_libraries(fakedecoshadows
PUBLIC
Qt5::Core
Qt5::Gui
PRIVATE
KDecoration2::KDecoration
KF5::CoreAddons)
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2018 Vlad Zagorodniy <vladzzag@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include <QPainter>
#include <KDecoration2/Decoration>
#include <KPluginFactory>
class FakeDecoWithShadows : public KDecoration2::Decoration
{
Q_OBJECT
public:
explicit FakeDecoWithShadows(QObject *parent = nullptr, const QVariantList &args = QVariantList())
: Decoration(parent, args) {}
~FakeDecoWithShadows() override {}
void paint(QPainter *painter, const QRect &repaintRegion) override {
Q_UNUSED(painter)
Q_UNUSED(repaintRegion)
}
public Q_SLOTS:
void init() override {
const int shadowSize = 128;
const int offsetTop = 64;
const int offsetLeft = 48;
const QRect shadowRect(0, 0, 4 * shadowSize + 1, 4 * shadowSize + 1);
QImage shadowTexture(shadowRect.size(), QImage::Format_ARGB32_Premultiplied);
shadowTexture.fill(Qt::transparent);
const QMargins padding(
shadowSize - offsetLeft,
shadowSize - offsetTop,
shadowSize + offsetLeft,
shadowSize + offsetTop);
auto decoShadow = QSharedPointer<KDecoration2::DecorationShadow>::create();
decoShadow->setPadding(padding);
decoShadow->setInnerShadowRect(QRect(shadowRect.center(), QSize(1, 1)));
decoShadow->setShadow(shadowTexture);
setShadow(decoShadow);
}
};
K_PLUGIN_FACTORY_WITH_JSON(
FakeDecoWithShadowsFactory,
"fakedecoration_with_shadows.json",
registerPlugin<FakeDecoWithShadows>();
)
#include "fakedecoration_with_shadows.moc"
{
"KPlugin": {
"Description": "Window decoration to test shadow tile overlaps",
"EnabledByDefault": false,
"Id": "org.kde.test.fakedecowithshadows",
"Name": "Fake Decoration With Shadows",
"ServiceTypes": [
"org.kde.kdecoration2"
]
},
"org.kde.kdecoration2": {
"blur": false,
"kcmodule": false
}
}
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment