feat: add news ticker with sentiment analysis and error codes

docs: update site links to retoor repository and documentation
chore: add author lines to header files
build: rebuild binary and object files
This commit is contained in:
2025-12-28 04:30:10 +01:00
parent 7a4f7a82ad
commit 9182d9931e
42 changed files with 262 additions and 76 deletions
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* AI Integration (OpenRouter API)
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Application launcher with .desktop file support
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* X11 Atoms management (EWMH/ICCCM compliance)
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Client (window) management
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Configuration system
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Window decorations (title bars, borders, buttons)
*/
+12
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Main header with shared types and global state
*/
@@ -32,6 +33,17 @@
#define DEFAULT_PANEL_HEIGHT 28
#define DEFAULT_GAP 4
/* Common error/status codes */
typedef enum {
DWN_OK = 0,
DWN_ERROR = -1,
DWN_ERROR_INVALID_ARG = -2,
DWN_ERROR_NO_MEMORY = -3,
DWN_ERROR_NOT_FOUND = -4,
DWN_ERROR_DISPLAY = -5,
DWN_ERROR_IO = -6
} DwnStatus;
/* Layout types */
typedef enum {
LAYOUT_TILING,
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Keyboard shortcut handling
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Layout algorithms (tiling, floating, monocle)
*/
+10
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* News ticker for bottom panel
*/
@@ -13,12 +14,21 @@
#define MAX_NEWS_ARTICLES 50
#define NEWS_API_URL "https://news.app.molodetz.nl/api"
/* Sentiment classification */
typedef enum {
SENTIMENT_NEUTRAL = 0,
SENTIMENT_POSITIVE,
SENTIMENT_NEGATIVE
} NewsSentiment;
/* News article */
typedef struct {
char title[256];
char content[1024];
char link[512];
char author[128];
NewsSentiment sentiment;
float sentiment_score;
} NewsArticle;
/* News ticker state */
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* D-Bus Notification daemon
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Panel system (top and bottom panels with widgets)
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* System tray widgets (WiFi, Audio, etc.)
*/
+6
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Utility functions
*/
@@ -9,6 +10,11 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdarg.h>
#include <assert.h>
/* Contract assertion macro - use for programmer errors */
#define DWN_ASSERT(cond) assert(cond)
#define DWN_ASSERT_MSG(cond, msg) assert((cond) && (msg))
/* Logging levels */
typedef enum {
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Workspace (tag/virtual desktop) management
*/
+7 -7
View File
@@ -28,7 +28,7 @@
<a href="architecture.html">Architecture</a>
</div>
</li>
<li><a href="https://github.com/dwn/dwn">GitHub</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn">Git</a></li>
</ul>
<div class="nav-toggle" onclick="toggleNav()">
<span></span>
@@ -434,21 +434,21 @@ model = google/gemini-2.0-flash-exp:free</code></pre>
<li><a href="features.html">Features</a></li>
<li><a href="installation.html">Installation</a></li>
<li><a href="ai-features.html">AI Integration</a></li>
<li><a href="https://github.com/dwn/dwn">GitHub</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn">Git</a></li>
</ul>
</div>
<div class="footer-section">
<h4>Community</h4>
<ul>
<li><a href="https://github.com/dwn/dwn/issues">Issue Tracker</a></li>
<li><a href="https://github.com/dwn/dwn/discussions">Discussions</a></li>
<li><a href="https://github.com/dwn/dwn/blob/main/CONTRIBUTING.md">Contributing</a></li>
<li><a href="https://github.com/dwn/dwn/blob/main/LICENSE">License (MIT)</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/issues">Issue Tracker</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/discussions">Discussions</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/blob/main/CONTRIBUTING.md">Contributing</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/blob/main/LICENSE">License (MIT)</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<p>DWN Window Manager - Open Source under the MIT License</p>
<p>DWN Window Manager by retoor &lt;retoor@molodetz.nl&gt; - MIT License</p>
</div>
</div>
</footer>
+7 -7
View File
@@ -28,7 +28,7 @@
<a href="architecture.html">Architecture</a>
</div>
</li>
<li><a href="https://github.com/dwn/dwn">GitHub</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn">Git</a></li>
</ul>
<div class="nav-toggle" onclick="toggleNav()">
<span></span>
@@ -541,21 +541,21 @@ extern DWNState *dwn; // Global singleton</code></pre>
<li><a href="features.html">Features</a></li>
<li><a href="installation.html">Installation</a></li>
<li><a href="ai-features.html">AI Integration</a></li>
<li><a href="https://github.com/dwn/dwn">GitHub</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn">Git</a></li>
</ul>
</div>
<div class="footer-section">
<h4>Community</h4>
<ul>
<li><a href="https://github.com/dwn/dwn/issues">Issue Tracker</a></li>
<li><a href="https://github.com/dwn/dwn/discussions">Discussions</a></li>
<li><a href="https://github.com/dwn/dwn/blob/main/CONTRIBUTING.md">Contributing</a></li>
<li><a href="https://github.com/dwn/dwn/blob/main/LICENSE">License (MIT)</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/issues">Issue Tracker</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/discussions">Discussions</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/blob/main/CONTRIBUTING.md">Contributing</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/blob/main/LICENSE">License (MIT)</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<p>DWN Window Manager - Open Source under the MIT License</p>
<p>DWN Window Manager by retoor &lt;retoor@molodetz.nl&gt; - MIT License</p>
</div>
</div>
</footer>
+7 -7
View File
@@ -28,7 +28,7 @@
<a href="architecture.html">Architecture</a>
</div>
</li>
<li><a href="https://github.com/dwn/dwn">GitHub</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn">Git</a></li>
</ul>
<div class="nav-toggle" onclick="toggleNav()">
<span></span>
@@ -496,21 +496,21 @@ model = google/gemini-2.0-flash-exp:free
<li><a href="features.html">Features</a></li>
<li><a href="installation.html">Installation</a></li>
<li><a href="ai-features.html">AI Integration</a></li>
<li><a href="https://github.com/dwn/dwn">GitHub</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn">Git</a></li>
</ul>
</div>
<div class="footer-section">
<h4>Community</h4>
<ul>
<li><a href="https://github.com/dwn/dwn/issues">Issue Tracker</a></li>
<li><a href="https://github.com/dwn/dwn/discussions">Discussions</a></li>
<li><a href="https://github.com/dwn/dwn/blob/main/CONTRIBUTING.md">Contributing</a></li>
<li><a href="https://github.com/dwn/dwn/blob/main/LICENSE">License (MIT)</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/issues">Issue Tracker</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/discussions">Discussions</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/blob/main/CONTRIBUTING.md">Contributing</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/blob/main/LICENSE">License (MIT)</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<p>DWN Window Manager - Open Source under the MIT License</p>
<p>DWN Window Manager by retoor &lt;retoor@molodetz.nl&gt; - MIT License</p>
</div>
</div>
</footer>
+11 -9
View File
@@ -28,7 +28,7 @@
<a href="architecture.html">Architecture</a>
</div>
</li>
<li><a href="https://github.com/dwn/dwn">GitHub</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn">Git</a></li>
</ul>
<div class="nav-toggle" onclick="toggleNav()">
<span></span>
@@ -360,8 +360,10 @@
<h3>Bottom Panel</h3>
<p>
The bottom panel shows the current time and date. Both panels can be hidden
in the configuration if you prefer a minimal setup.
The bottom panel shows the current time and a scrolling news ticker. Navigate
news articles with <kbd>Super</kbd> + <kbd>Up</kbd>/<kbd>Down</kbd> and open
the current article with <kbd>Super</kbd> + <kbd>Return</kbd>. Both panels can
be hidden in the configuration if you prefer a minimal setup.
</p>
<h2>Next Steps</h2>
@@ -399,21 +401,21 @@
<li><a href="features.html">Features</a></li>
<li><a href="installation.html">Installation</a></li>
<li><a href="ai-features.html">AI Integration</a></li>
<li><a href="https://github.com/dwn/dwn">GitHub</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn">Git</a></li>
</ul>
</div>
<div class="footer-section">
<h4>Community</h4>
<ul>
<li><a href="https://github.com/dwn/dwn/issues">Issue Tracker</a></li>
<li><a href="https://github.com/dwn/dwn/discussions">Discussions</a></li>
<li><a href="https://github.com/dwn/dwn/blob/main/CONTRIBUTING.md">Contributing</a></li>
<li><a href="https://github.com/dwn/dwn/blob/main/LICENSE">License (MIT)</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/issues">Issue Tracker</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/discussions">Discussions</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/blob/main/CONTRIBUTING.md">Contributing</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/blob/main/LICENSE">License (MIT)</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<p>DWN Window Manager - Open Source under the MIT License</p>
<p>DWN Window Manager by retoor &lt;retoor@molodetz.nl&gt; - MIT License</p>
</div>
</div>
</footer>
+23 -8
View File
@@ -28,7 +28,7 @@
<a href="architecture.html">Architecture</a>
</div>
</li>
<li><a href="https://github.com/dwn/dwn">GitHub</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn">Git</a></li>
</ul>
<div class="nav-toggle" onclick="toggleNav()">
<span></span>
@@ -160,12 +160,27 @@
<p>Optional bottom panel for additional information:</p>
<ul style="margin-top: 1rem; padding-left: 1.25rem; color: var(--text-muted);">
<li><strong>Clock Display</strong> - Time and date</li>
<li><strong>Status Messages</strong> - System notifications</li>
<li><strong>News Ticker</strong> - Scrolling news feed with navigation</li>
<li><strong>Customizable</strong> - Can be hidden in config</li>
</ul>
</div>
</div>
<h3 style="margin-top: 3rem; margin-bottom: 1.5rem;">News Ticker</h3>
<div class="card">
<p>The bottom panel includes a scrolling news ticker that displays headlines from a news feed.
Navigate through articles using keyboard shortcuts:</p>
<ul style="margin-top: 1rem; padding-left: 1.25rem; color: var(--text-muted);">
<li><kbd>Super</kbd> + <kbd>Down</kbd> - Next article</li>
<li><kbd>Super</kbd> + <kbd>Up</kbd> - Previous article</li>
<li><kbd>Super</kbd> + <kbd>Return</kbd> - Open in browser</li>
</ul>
<p style="margin-top: 1rem; color: var(--text-muted);">
The ticker updates automatically and caches up to 50 articles. Smooth scrolling animation
at 80 pixels per second keeps you informed without distraction.
</p>
</div>
<h3 style="margin-top: 3rem; margin-bottom: 1.5rem;">System Tray Features</h3>
<div class="features-grid">
<div class="card">
@@ -387,21 +402,21 @@
<li><a href="features.html">Features</a></li>
<li><a href="installation.html">Installation</a></li>
<li><a href="ai-features.html">AI Integration</a></li>
<li><a href="https://github.com/dwn/dwn">GitHub</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn">Git</a></li>
</ul>
</div>
<div class="footer-section">
<h4>Community</h4>
<ul>
<li><a href="https://github.com/dwn/dwn/issues">Issue Tracker</a></li>
<li><a href="https://github.com/dwn/dwn/discussions">Discussions</a></li>
<li><a href="https://github.com/dwn/dwn/blob/main/CONTRIBUTING.md">Contributing</a></li>
<li><a href="https://github.com/dwn/dwn/blob/main/LICENSE">License (MIT)</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/issues">Issue Tracker</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/discussions">Discussions</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/blob/main/CONTRIBUTING.md">Contributing</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/blob/main/LICENSE">License (MIT)</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<p>DWN Window Manager - Open Source under the MIT License</p>
<p>DWN Window Manager by retoor &lt;retoor@molodetz.nl&gt; - MIT License</p>
</div>
</div>
</footer>
+10 -10
View File
@@ -29,7 +29,7 @@
<a href="architecture.html">Architecture</a>
</div>
</li>
<li><a href="https://github.com/dwn/dwn">GitHub</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn">Git</a></li>
</ul>
<div class="nav-toggle" onclick="toggleNav()">
<span></span>
@@ -109,7 +109,7 @@
<div class="container">
<div class="stats">
<div class="stat-item">
<h3>~10K</h3>
<h3>~15K</h3>
<p>Lines of Pure C</p>
</div>
<div class="stat-item">
@@ -121,7 +121,7 @@
<p>Memory Footprint</p>
</div>
<div class="stat-item">
<h3>64+</h3>
<h3>43+</h3>
<p>Keyboard Shortcuts</p>
</div>
</div>
@@ -143,7 +143,7 @@
<button class="copy-btn" onclick="copyCode(this)">Copy</button>
</div>
<pre><code># Clone the repository
git clone https://github.com/dwn/dwn.git
git clone https://retoor.molodetz.nl/retoor/dwn.git
cd dwn
# Install dependencies (auto-detects your distro)
@@ -328,21 +328,21 @@ echo "exec dwn" >> ~/.xinitrc</code></pre>
<li><a href="features.html">Features</a></li>
<li><a href="installation.html">Installation</a></li>
<li><a href="ai-features.html">AI Integration</a></li>
<li><a href="https://github.com/dwn/dwn">GitHub</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn">Git</a></li>
</ul>
</div>
<div class="footer-section">
<h4>Community</h4>
<ul>
<li><a href="https://github.com/dwn/dwn/issues">Issue Tracker</a></li>
<li><a href="https://github.com/dwn/dwn/discussions">Discussions</a></li>
<li><a href="https://github.com/dwn/dwn/blob/main/CONTRIBUTING.md">Contributing</a></li>
<li><a href="https://github.com/dwn/dwn/blob/main/LICENSE">License (MIT)</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/issues">Issue Tracker</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/discussions">Discussions</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/blob/main/CONTRIBUTING.md">Contributing</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/blob/main/LICENSE">License (MIT)</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<p>DWN Window Manager - Open Source under the MIT License</p>
<p>DWN Window Manager by retoor &lt;retoor@molodetz.nl&gt; - MIT License</p>
</div>
</div>
</footer>
+12 -12
View File
@@ -28,7 +28,7 @@
<a href="architecture.html">Architecture</a>
</div>
</li>
<li><a href="https://github.com/dwn/dwn">GitHub</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn">Git</a></li>
</ul>
<div class="nav-toggle" onclick="toggleNav()">
<span></span>
@@ -133,7 +133,7 @@
<span>Terminal</span>
<button class="copy-btn" onclick="copyCode(this)">Copy</button>
</div>
<pre><code>git clone https://github.com/dwn/dwn.git
<pre><code>git clone https://retoor.molodetz.nl/retoor/dwn.git
cd dwn</code></pre>
</div>
</div>
@@ -232,7 +232,7 @@ sudo apt install -y \
pkg-config
# Build and install
git clone https://github.com/dwn/dwn.git
git clone https://retoor.molodetz.nl/retoor/dwn.git
cd dwn
make
sudo make install</code></pre>
@@ -259,7 +259,7 @@ sudo dnf install -y \
pkg-config
# Build and install
git clone https://github.com/dwn/dwn.git
git clone https://retoor.molodetz.nl/retoor/dwn.git
cd dwn
make
sudo make install</code></pre>
@@ -285,7 +285,7 @@ sudo pacman -S --needed \
pkg-config
# Build and install
git clone https://github.com/dwn/dwn.git
git clone https://retoor.molodetz.nl/retoor/dwn.git
cd dwn
make
sudo make install</code></pre>
@@ -316,7 +316,7 @@ sudo xbps-install -S \
pkg-config
# Build and install
git clone https://github.com/dwn/dwn.git
git clone https://retoor.molodetz.nl/retoor/dwn.git
cd dwn
make
sudo make install</code></pre>
@@ -586,21 +586,21 @@ sudo dnf install dejavu-fonts-all liberation-fonts # Fedora</code></pre>
<li><a href="features.html">Features</a></li>
<li><a href="installation.html">Installation</a></li>
<li><a href="ai-features.html">AI Integration</a></li>
<li><a href="https://github.com/dwn/dwn">GitHub</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn">Git</a></li>
</ul>
</div>
<div class="footer-section">
<h4>Community</h4>
<ul>
<li><a href="https://github.com/dwn/dwn/issues">Issue Tracker</a></li>
<li><a href="https://github.com/dwn/dwn/discussions">Discussions</a></li>
<li><a href="https://github.com/dwn/dwn/blob/main/CONTRIBUTING.md">Contributing</a></li>
<li><a href="https://github.com/dwn/dwn/blob/main/LICENSE">License (MIT)</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/issues">Issue Tracker</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/discussions">Discussions</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/blob/main/CONTRIBUTING.md">Contributing</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/blob/main/LICENSE">License (MIT)</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<p>DWN Window Manager - Open Source under the MIT License</p>
<p>DWN Window Manager by retoor &lt;retoor@molodetz.nl&gt; - MIT License</p>
</div>
</div>
</footer>
+42 -8
View File
@@ -28,7 +28,7 @@
<a href="architecture.html">Architecture</a>
</div>
</li>
<li><a href="https://github.com/dwn/dwn">GitHub</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn">Git</a></li>
</ul>
<div class="nav-toggle" onclick="toggleNav()">
<span></span>
@@ -71,7 +71,7 @@
<td>Open terminal (configurable)</td>
</tr>
<tr>
<td><kbd>Alt</kbd> + <kbd>F2</kbd></td>
<td><kbd>Super</kbd> / <kbd>Alt</kbd> + <kbd>F2</kbd></td>
<td>Open application launcher (dmenu/rofi)</td>
</tr>
<tr>
@@ -82,6 +82,10 @@
<td><kbd>Super</kbd> + <kbd>B</kbd></td>
<td>Open web browser</td>
</tr>
<tr>
<td><kbd>Print</kbd></td>
<td>Take screenshot (xfce4-screenshooter)</td>
</tr>
</tbody>
</table>
</div>
@@ -285,6 +289,36 @@
</table>
</div>
<!-- News Ticker -->
<h2 id="news">News Ticker</h2>
<p style="color: var(--text-muted); margin-bottom: 1rem;">
Navigate the scrolling news ticker displayed in the bottom panel.
</p>
<div class="table-wrapper">
<table class="shortcuts-table">
<thead>
<tr>
<th style="width: 40%;">Shortcut</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td><kbd>Super</kbd> + <kbd>Down</kbd></td>
<td>Next news article</td>
</tr>
<tr>
<td><kbd>Super</kbd> + <kbd>Up</kbd></td>
<td>Previous news article</td>
</tr>
<tr>
<td><kbd>Super</kbd> + <kbd>Return</kbd></td>
<td>Open current article in browser</td>
</tr>
</tbody>
</table>
</div>
<!-- Help & System -->
<h2 id="system">Help & System</h2>
<div class="table-wrapper">
@@ -389,21 +423,21 @@
<li><a href="features.html">Features</a></li>
<li><a href="installation.html">Installation</a></li>
<li><a href="ai-features.html">AI Integration</a></li>
<li><a href="https://github.com/dwn/dwn">GitHub</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn">Git</a></li>
</ul>
</div>
<div class="footer-section">
<h4>Community</h4>
<ul>
<li><a href="https://github.com/dwn/dwn/issues">Issue Tracker</a></li>
<li><a href="https://github.com/dwn/dwn/discussions">Discussions</a></li>
<li><a href="https://github.com/dwn/dwn/blob/main/CONTRIBUTING.md">Contributing</a></li>
<li><a href="https://github.com/dwn/dwn/blob/main/LICENSE">License (MIT)</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/issues">Issue Tracker</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/discussions">Discussions</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/blob/main/CONTRIBUTING.md">Contributing</a></li>
<li><a href="https://retoor.molodetz.nl/retoor/dwn/blob/main/LICENSE">License (MIT)</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<p>DWN Window Manager - Open Source under the MIT License</p>
<p>DWN Window Manager by retoor &lt;retoor@molodetz.nl&gt; - MIT License</p>
</div>
</div>
</footer>
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* AI Integration implementation
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Application launcher with .desktop file support
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* X11 Atoms management implementation
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Client (window) management implementation
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Configuration system implementation
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Window decorations implementation
*/
+41 -3
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Keyboard shortcut handling implementation
*/
@@ -15,6 +16,11 @@
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <X11/XKBlib.h>
static bool super_pressed = false;
static bool super_used_in_combo = false;
/* Forward declarations for key callbacks */
void key_spawn_terminal(void);
@@ -354,6 +360,17 @@ void keys_grab_all(void)
GrabModeAsync, GrabModeAsync);
}
}
KeyCode super_l = XKeysymToKeycode(dpy, XK_Super_L);
KeyCode super_r = XKeysymToKeycode(dpy, XK_Super_R);
unsigned int lock_mods[] = { 0, Mod2Mask, LockMask, Mod2Mask | LockMask };
for (size_t i = 0; i < sizeof(lock_mods) / sizeof(lock_mods[0]); i++) {
if (super_l) XGrabKey(dpy, super_l, lock_mods[i], root, True,
GrabModeAsync, GrabModeAsync);
if (super_r) XGrabKey(dpy, super_r, lock_mods[i], root, True,
GrabModeAsync, GrabModeAsync);
}
}
void keys_ungrab_all(void)
@@ -412,6 +429,16 @@ void keys_handle_press(XKeyEvent *ev)
KeySym keysym = XLookupKeysym(ev, 0);
if (keysym == XK_Super_L || keysym == XK_Super_R) {
super_pressed = true;
super_used_in_combo = false;
return;
}
if (super_pressed && (ev->state & Mod4Mask)) {
super_used_in_combo = true;
}
/* Clean modifiers (remove NumLock, CapsLock) */
unsigned int clean_mask = ev->state & ~(Mod2Mask | LockMask);
@@ -434,8 +461,19 @@ void keys_handle_press(XKeyEvent *ev)
void keys_handle_release(XKeyEvent *ev)
{
/* Currently no release handling needed */
(void)ev;
if (ev == NULL || dwn == NULL || dwn->display == NULL) {
return;
}
KeySym keysym = XLookupKeysym(ev, 0);
if (keysym == XK_Super_L || keysym == XK_Super_R) {
if (super_pressed && !super_used_in_combo) {
key_spawn_launcher();
}
super_pressed = false;
super_used_in_combo = false;
}
}
/* ========== Default key bindings (XFCE-style) ========== */
@@ -770,7 +808,7 @@ void key_show_shortcuts(void)
const char *shortcuts =
"=== Applications ===\n"
"Ctrl+Alt+T Terminal\n"
"Alt+F2 App launcher\n"
"Super / Alt+F2 App launcher\n"
"Super+E File manager\n"
"Super+B Web browser\n"
"Print Screenshot\n"
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Layout algorithms implementation
*/
+9 -4
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Main entry point and event loop
*/
@@ -456,15 +457,19 @@ static void handle_button_press(XButtonEvent *ev)
return;
}
/* Focus on click */
client_focus(c);
/* If click was on client window content, replay the event to the application */
/* If click was on client window content, replay the event to the application FIRST
* before any other X operations. The synchronous grab freezes pointer events until
* XAllowEvents is called. Calling XAllowEvents before client_focus ensures the
* click reaches the application (tabs, buttons, etc.) without timing issues. */
if (is_client_window) {
XAllowEvents(dwn->display, ReplayPointer, ev->time);
client_focus(c);
return;
}
/* Focus on click */
client_focus(c);
/* Check for button clicks in decorations */
if (c->frame != None && ev->window == c->frame) {
ButtonType btn = decorations_hit_test_button(c, ev->x, ev->y);
+41 -1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* News ticker implementation
*/
@@ -12,6 +13,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <sys/wait.h>
#include <pthread.h>
@@ -24,6 +26,20 @@
/* Fetch interval in milliseconds (5 minutes) */
#define FETCH_INTERVAL 300000
/* Sentiment colors (RGB hex values) */
#define SENTIMENT_COLOR_POSITIVE 0x81C784
#define SENTIMENT_COLOR_NEUTRAL 0xB0BEC5
#define SENTIMENT_COLOR_NEGATIVE 0xE57373
static unsigned long news_sentiment_color(NewsSentiment sentiment)
{
switch (sentiment) {
case SENTIMENT_POSITIVE: return SENTIMENT_COLOR_POSITIVE;
case SENTIMENT_NEGATIVE: return SENTIMENT_COLOR_NEGATIVE;
default: return SENTIMENT_COLOR_NEUTRAL;
}
}
/* Global state */
NewsState news_state = {0};
@@ -225,6 +241,27 @@ static int parse_news_json(const char *json_str)
strncpy(art->author, author->valuestring, sizeof(art->author) - 1);
}
cJSON *sentiment_obj = cJSON_GetObjectItemCaseSensitive(article, "sentiment");
if (cJSON_IsObject(sentiment_obj)) {
cJSON *sentiment_type = cJSON_GetObjectItemCaseSensitive(sentiment_obj, "sentiment");
cJSON *sentiment_score = cJSON_GetObjectItemCaseSensitive(sentiment_obj, "score");
if (cJSON_IsString(sentiment_type) && sentiment_type->valuestring) {
if (strcasecmp(sentiment_type->valuestring, "Positive") == 0) {
art->sentiment = SENTIMENT_POSITIVE;
} else if (strcasecmp(sentiment_type->valuestring, "Negative") == 0) {
art->sentiment = SENTIMENT_NEGATIVE;
} else {
art->sentiment = SENTIMENT_NEUTRAL;
}
}
if (cJSON_IsNumber(sentiment_score)) {
art->sentiment_score = (float)sentiment_score->valuedouble;
}
}
count++;
}
@@ -630,9 +667,12 @@ void news_render(Panel *panel, int x, int max_width, int *used_width)
char display_text[2048];
get_article_display_text(current_article, display_text, sizeof(display_text));
unsigned long article_color = news_sentiment_color(
news_state.articles[current_article].sentiment);
if (draw_x + news_state.display_widths[current_article] > x) {
news_draw_text_clipped(panel->buffer, draw_x, text_y, display_text,
colors->panel_fg, &clip_rect);
article_color, &clip_rect);
}
draw_x += news_state.display_widths[current_article];
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* D-Bus Notification daemon implementation
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Panel system implementation
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* System tray widgets implementation with UTF-8 support
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Utility functions implementation
*/
+1
View File
@@ -1,5 +1,6 @@
/*
* DWN - Desktop Window Manager
* retoor <retoor@molodetz.nl>
* Workspace management implementation
*/