Full Code of esjeon/kwin-forceblur for AI

master 1f92ed59d4e4 cached
9 files
12.0 KB
3.5k tokens
1 requests
Download .txt
Repository: esjeon/kwin-forceblur
Branch: master
Commit: 1f92ed59d4e4
Files: 9
Total size: 12.0 KB

Directory structure:
gitextract_ohvpcgjx/

├── .gitignore
├── LICENSE
├── README.md
├── contents/
│   ├── config/
│   │   └── main.xml
│   └── ui/
│       ├── config.ui
│       └── main.qml
├── install.sh
├── metadata.desktop
└── pack.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
forceblur.kwinscript


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2019 Eon S. Jeon <esjeon@hyunmu.am>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================

Force Blur
==========

A KWin script to force-enable KWin Blur effect on user-specified windows.

![](image.png)

This is more useful than shell script hacks, because KWin script receives event
notification and window info from KWin. This can also fix tray-based apps,
which loses blur hints when restored from system tray.


System Requirement
------------------

* Operating System:
  - (K)Ubuntu 18.10 or newer
  - Fedora 29 or newer
  - Arch Linux - kwin 5.14 or newer

* Make sure you're using "Blur" desktop effect, which can be enabled through System Settings.

* This script internally calls `xprop` command, which would be already installed
  on your system.

* X11 display server (the script does not support wayland applications)


How to Use
----------

1. Install the script.

2. Run the following in terminal, to enable script configuration:

        mkdir -p ~/.local/share/kservices5/
        cp ~/.local/share/kwin/scripts/forceblur/metadata.desktop ~/.local/share/kservices5/forceblur.desktop

3. Open `Kwin Scripts` page in `System Settings`.

4. Enable `Force Blur` script by checking the checkbox next to it.

5. Change script settings. Note that the script can only match with window classes.

6. Click `OK` to enable the script.

7. Whenever settings are changed, you must disable and re-enable the script.  
   (Uncheck -> `Apply` -> Check -> `Apply`)


GTK CSD Shadow
--------------

Some GTK applications render client-side shadows, which look ugly if blurred. To
prevent this, you can enable "**Blur only the content of window**" option.

This works by updating the blur region info whenever a window is resized, so
might have some performance impacts. Use with caution.


Authors
-------

* Eon S. Jeon <esjeon@hyunmu.am> - main author
* Aaron Miller (https://github.com/aaronm-cloudtek) - blacklist mode



================================================
FILE: contents/config/main.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
                          http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
  <kcfgfile name=""/>
  <group name="">
    <entry name="patterns" type="String">
      <label>Comma-separated list of window classes</label>
        <default>yakuake
urxvt
keepassxc</default>
    </entry>
    <entry name="blurMatching" type="Bool">
      <default>true</default>
    </entry>
    <entry name="blurExceptMatching" type="Bool">
      <default>false</default>
    </entry>
    <entry name="blurContent" type="Bool">
      <default>false</default>
    </entry>
  </group>
</kcfg>


================================================
FILE: contents/ui/config.ui
================================================
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>ForceBlurConfigForm</class>
 <widget class="QWidget" name="ForceBlurConfigForm">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>400</height>
   </rect>
  </property>
  <property name="minimumSize">
   <size>
    <width>400</width>
    <height>350</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout_2">
   <item>
    <widget class="QGroupBox" name="groupMatching">
     <property name="title">
      <string>Window Matching</string>
     </property>
     <layout class="QVBoxLayout" name="layoutMatching">
      <item>
       <widget class="QLabel" name="labelMatching">
        <property name="whatsThis">
         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;&amp;lt;&amp;lt;Example&amp;gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;yakuake&lt;/p&gt;&lt;p&gt;keepassxc&lt;/p&gt;&lt;p&gt;urxvt&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
        <property name="text">
         <string notr="true">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enter window class names, &lt;span style=&quot; text-decoration: underline;&quot;&gt;one per line&lt;/span&gt;.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QPlainTextEdit" name="kcfg_patterns">
        <property name="toolTip">
         <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Fira Sans Book'; font-size:11pt; font-weight:232; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Enter the class names of the windows you want to enable/disable blurring.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Class names can be obtained by using &lt;span style=&quot; font-weight:600;&quot;&gt;xprop&lt;/span&gt; utility in terminal. (xprop WM_CLASS)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
       </widget>
      </item>
      <item>
       <layout class="QHBoxLayout" name="layoutMatchingMode">
        <item>
         <widget class="QRadioButton" name="kcfg_blurMatching">
          <property name="text">
           <string>Blur only matching</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QRadioButton" name="kcfg_blurExceptMatching">
          <property name="text">
           <string>Blur all except matching</string>
          </property>
         </widget>
        </item>
       </layout>
      </item>
     </layout>
    </widget>
   </item>
   <item>
    <widget class="QGroupBox" name="groupOptions">
     <property name="title">
      <string>Options</string>
     </property>
     <layout class="QVBoxLayout" name="verticalLayout">
      <item>
       <widget class="QCheckBox" name="kcfg_blurContent">
        <property name="toolTip">
         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enabling this option prevents blurring behind the non-content regions of window, like &lt;span style=&quot; font-weight:600;&quot;&gt;CSD shadows in GTK&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;This &lt;span style=&quot; text-decoration: underline;&quot;&gt;might&lt;/span&gt; cause performance issues and flickers, thus users should be careful about turning this on.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
        <property name="text">
         <string>Blur only the content of window</string>
        </property>
       </widget>
      </item>
     </layout>
    </widget>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
 <buttongroups>
  <buttongroup name="matchTypeGroup"/>
 </buttongroups>
</ui>


================================================
FILE: contents/ui/main.qml
================================================
import QtQuick 2.0
import org.kde.plasma.core 2.0 as PlasmaCore;
import org.kde.plasma.components 2.0 as Plasma;
import org.kde.kwin 2.0;

Item {
    id: root

    readonly property var patterns: (
        KWin.readConfig("patterns", "yakuake\nurxvt\nkeepassxc")
            .split("\n")
            .map(function(rule) {
                return rule.trim().toLowerCase();
            })
    )

    readonly property var blurMatching: (
        KWin.readConfig("blurMatching", true)
    )

    readonly property var blurContent: (
        KWin.readConfig("blurContent", false)
    )

    PlasmaCore.DataSource {
        id: shell
        engine: 'executable'

        connectedSources: []

        function run(cmd) {
            shell.connectSource(cmd);
        }

        onNewData: {
            shell.disconnectSource(sourceName);
        }
    }

    function onClientAdded(client) {
        if (!shell) return;

        var cls = client.resourceClass.toString().toLowerCase();
        var name = client.resourceName.toString().toLowerCase();
        var clsMatches = root.patterns.indexOf(cls) >= 0 || root.patterns.indexOf(name) >= 0;

        if (clsMatches == root.blurMatching) {
            if (root.blurContent) {
                registerHintUpdater(client);
            } else {
                var wid = "0x" + client.windowId.toString(16);
                shell.run("xprop -f _KDE_NET_WM_BLUR_BEHIND_REGION 32c -set _KDE_NET_WM_BLUR_BEHIND_REGION 0 -id " + wid);
            }
        }
    }

    function registerHintUpdater(client) {
        var prevWidth  = client.geometry.width;
        var prevHeight = client.geometry.height;
        var handler = function() {
            try { if (!root) return; } catch(e) {
                client.geometryChanged.disconnect(handler);
                throw e;
            }

            root.onClientGeometryChanged(client, prevWidth, prevHeight);

            prevWidth  = client.geometry.width;
            prevHeight = client.geometry.height;
        }

        client.geometryChanged.connect(handler);
        root.onClientGeometryChanged(client, 0, 0);
    }

    function onClientGeometryChanged(client, prevWidth, prevHeight) {
        if (!shell) return;

        /* Skip if window *size* isn't really changed */
        if (client.geometry.width === prevWidth && client.geometry.height === prevHeight)
            return;

        var wid = "0x" + client.windowId.toString(16);
        var region = "0,0," + client.geometry.width + "," + client.geometry.height;
        var cmd = "xprop -id " + wid + " -f _KDE_NET_WM_BLUR_BEHIND_REGION 32c -set _KDE_NET_WM_BLUR_BEHIND_REGION " + region
        shell.run(cmd);
    }

    Component.onCompleted: {
        console.log("FORCE-BLUR: starting the script");
        console.log(JSON.stringify(root.patterns));

        var clients = workspace.clientList();
        for (var i = 0; i < clients.length; i++) {
            root.onClientAdded(clients[i]);
        }

        workspace.onClientAdded.connect(root.onClientAdded);
    }
}


================================================
FILE: install.sh
================================================
#!/bin/sh
set -euf

if [[ ! -f forceblur.kwinscript ]]; then
	echo "Error: can't find package file: $PWD/forceblur.kwinscript"
	echo "Please run 'pack' first"
	exit 1
fi >&2

plasmapkg2 -i forceblur.kwinscript || plasmapkg2 -u forceblur.kwinscript
mkdir -pv ~/.local/share/kservices5/
cp -vf metadata.desktop ~/.local/share/kservices5/forceblur.desktop



================================================
FILE: metadata.desktop
================================================
[Desktop Entry]
Name=Force Blur
Comment=Force-enable Blur effect for certain windows
Icon=preferences-system-windows-script-test

X-Plasma-API=declarativescript
X-Plasma-MainScript=ui/main.qml

X-KDE-PluginInfo-Author=Eon S. Jeon
X-KDE-PluginInfo-Email=esjeon@hyunmu.am
X-KDE-PluginInfo-Name=forceblur
X-KDE-PluginInfo-Version=0.6
X-KDE-PluginInfo-License=MIT

Type=Service
X-KDE-ServiceTypes=KWin/Script

X-KDE-ConfigModule=kwin/effects/configs/kcm_kwin4_genericscripted


================================================
FILE: pack.sh
================================================
#!/bin/sh
set -eu

if ! type zip >&/dev/null; then
	echo "Error: Can't find 'zip' command."
	echo "       Please install 'zip' command first."
	exit 1
fi >&2

file=forceblur.kwinscript
rm -rvf "$file"
exec zip -r9 "$file" \
	README.md \
	LICENSE \
	metadata.desktop \
	contents \
Download .txt
gitextract_ohvpcgjx/

├── .gitignore
├── LICENSE
├── README.md
├── contents/
│   ├── config/
│   │   └── main.xml
│   └── ui/
│       ├── config.ui
│       └── main.qml
├── install.sh
├── metadata.desktop
└── pack.sh
Condensed preview — 9 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (13K chars).
[
  {
    "path": ".gitignore",
    "chars": 21,
    "preview": "forceblur.kwinscript\n"
  },
  {
    "path": "LICENSE",
    "chars": 1087,
    "preview": "MIT License\n\nCopyright (c) 2019 Eon S. Jeon <esjeon@hyunmu.am>\n\nPermission is hereby granted, free of charge, to any per"
  },
  {
    "path": "README.md",
    "chars": 1835,
    "preview": "\nForce Blur\n==========\n\nA KWin script to force-enable KWin Blur effect on user-specified windows.\n\n![](image.png)\n\nThis "
  },
  {
    "path": "contents/config/main.xml",
    "chars": 784,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kcfg xmlns=\"http://www.kde.org/standards/kcfg/1.0\"\n      xmlns:xsi=\"http://www.w"
  },
  {
    "path": "contents/ui/config.ui",
    "chars": 4459,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>ForceBlurConfigForm</class>\n <widget class=\"QWidget\" n"
  },
  {
    "path": "contents/ui/main.qml",
    "chars": 3046,
    "preview": "import QtQuick 2.0\nimport org.kde.plasma.core 2.0 as PlasmaCore;\nimport org.kde.plasma.components 2.0 as Plasma;\nimport "
  },
  {
    "path": "install.sh",
    "chars": 354,
    "preview": "#!/bin/sh\nset -euf\n\nif [[ ! -f forceblur.kwinscript ]]; then\n\techo \"Error: can't find package file: $PWD/forceblur.kwins"
  },
  {
    "path": "metadata.desktop",
    "chars": 472,
    "preview": "[Desktop Entry]\nName=Force Blur\nComment=Force-enable Blur effect for certain windows\nIcon=preferences-system-windows-scr"
  },
  {
    "path": "pack.sh",
    "chars": 280,
    "preview": "#!/bin/sh\nset -eu\n\nif ! type zip >&/dev/null; then\n\techo \"Error: Can't find 'zip' command.\"\n\techo \"       Please install"
  }
]

About this extraction

This page contains the full source code of the esjeon/kwin-forceblur GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 9 files (12.0 KB), approximately 3.5k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!