feat: add expose all windows and Alt-drag window manipulation
feat: improve maximize behavior with floating state and constraints feat: enhance resize cursors and edge detection
This commit is contained in:
parent
6b143990bb
commit
527f644a94
BIN
build/ai.o
BIN
build/ai.o
Binary file not shown.
Binary file not shown.
BIN
build/atoms.o
BIN
build/atoms.o
Binary file not shown.
Binary file not shown.
BIN
build/cJSON.o
BIN
build/cJSON.o
Binary file not shown.
BIN
build/client.o
BIN
build/client.o
Binary file not shown.
BIN
build/config.o
BIN
build/config.o
Binary file not shown.
Binary file not shown.
BIN
build/demo.o
BIN
build/demo.o
Binary file not shown.
@ -19,7 +19,7 @@ build/keys.o: src/keys.c include/keys.h include/dwn.h include/client.h \
|
|||||||
/usr/include/dbus-1.0/dbus/dbus-syntax.h \
|
/usr/include/dbus-1.0/dbus/dbus-syntax.h \
|
||||||
/usr/include/dbus-1.0/dbus/dbus-threads.h include/news.h \
|
/usr/include/dbus-1.0/dbus/dbus-threads.h include/news.h \
|
||||||
include/applauncher.h include/decorations.h include/demo.h \
|
include/applauncher.h include/decorations.h include/demo.h \
|
||||||
include/layout.h include/api.h include/marks.h
|
include/layout.h include/api.h include/marks.h include/panel.h
|
||||||
include/keys.h:
|
include/keys.h:
|
||||||
include/dwn.h:
|
include/dwn.h:
|
||||||
include/client.h:
|
include/client.h:
|
||||||
@ -53,3 +53,4 @@ include/demo.h:
|
|||||||
include/layout.h:
|
include/layout.h:
|
||||||
include/api.h:
|
include/api.h:
|
||||||
include/marks.h:
|
include/marks.h:
|
||||||
|
include/panel.h:
|
||||||
|
|||||||
BIN
build/keys.o
BIN
build/keys.o
Binary file not shown.
BIN
build/layout.o
BIN
build/layout.o
Binary file not shown.
BIN
build/main.o
BIN
build/main.o
Binary file not shown.
BIN
build/news.o
BIN
build/news.o
Binary file not shown.
Binary file not shown.
BIN
build/panel.o
BIN
build/panel.o
Binary file not shown.
BIN
build/systray.o
BIN
build/systray.o
Binary file not shown.
BIN
build/util.o
BIN
build/util.o
Binary file not shown.
Binary file not shown.
@ -125,6 +125,7 @@ struct Client {
|
|||||||
char title[256];
|
char title[256];
|
||||||
char class[64];
|
char class[64];
|
||||||
SnapConstraint snap;
|
SnapConstraint snap;
|
||||||
|
bool floating_before_maximize;
|
||||||
unsigned long taskbar_color;
|
unsigned long taskbar_color;
|
||||||
ColorAnimation title_anim;
|
ColorAnimation title_anim;
|
||||||
TextGlowAnimation text_glow;
|
TextGlowAnimation text_glow;
|
||||||
@ -219,6 +220,17 @@ typedef struct {
|
|||||||
int last_mouse_x;
|
int last_mouse_x;
|
||||||
int last_mouse_y;
|
int last_mouse_y;
|
||||||
bool mouse_tracking_initialized;
|
bool mouse_tracking_initialized;
|
||||||
|
|
||||||
|
Cursor cursor_default;
|
||||||
|
Cursor cursor_resize_top_left;
|
||||||
|
Cursor cursor_resize_top_right;
|
||||||
|
Cursor cursor_resize_bottom_left;
|
||||||
|
Cursor cursor_resize_bottom_right;
|
||||||
|
Cursor cursor_resize_left;
|
||||||
|
Cursor cursor_resize_right;
|
||||||
|
Cursor cursor_resize_top;
|
||||||
|
Cursor cursor_resize_bottom;
|
||||||
|
Cursor cursor_move;
|
||||||
} DWNState;
|
} DWNState;
|
||||||
|
|
||||||
#define PHASE_OFFSET_PANEL_BG 0.0f
|
#define PHASE_OFFSET_PANEL_BG 0.0f
|
||||||
|
|||||||
@ -100,6 +100,7 @@ void key_resize_window_up(void);
|
|||||||
void key_resize_window_down(void);
|
void key_resize_window_down(void);
|
||||||
void key_set_mark(void);
|
void key_set_mark(void);
|
||||||
void key_goto_mark(void);
|
void key_goto_mark(void);
|
||||||
|
void key_expose_all(void);
|
||||||
|
|
||||||
void tutorial_start(void);
|
void tutorial_start(void);
|
||||||
void tutorial_stop(void);
|
void tutorial_stop(void);
|
||||||
|
|||||||
41
src/client.c
41
src/client.c
@ -53,6 +53,7 @@ Client *client_create(Window window)
|
|||||||
client->snap.horizontal = SNAP_H_NONE;
|
client->snap.horizontal = SNAP_H_NONE;
|
||||||
client->snap.vertical = SNAP_V_NONE;
|
client->snap.vertical = SNAP_V_NONE;
|
||||||
client->snap.timestamp = 0;
|
client->snap.timestamp = 0;
|
||||||
|
client->floating_before_maximize = false;
|
||||||
|
|
||||||
XWindowAttributes wa;
|
XWindowAttributes wa;
|
||||||
int orig_width = 640, orig_height = 480;
|
int orig_width = 640, orig_height = 480;
|
||||||
@ -234,6 +235,16 @@ Client *client_manage(Window window)
|
|||||||
XGrabButton(dwn->display, Button1, AnyModifier, window, False,
|
XGrabButton(dwn->display, Button1, AnyModifier, window, False,
|
||||||
ButtonPressMask, GrabModeSync, GrabModeAsync, None, None);
|
ButtonPressMask, GrabModeSync, GrabModeAsync, None, None);
|
||||||
|
|
||||||
|
unsigned int lock_combos[] = { 0, Mod2Mask, LockMask, Mod2Mask | LockMask };
|
||||||
|
for (size_t gi = 0; gi < sizeof(lock_combos) / sizeof(lock_combos[0]); gi++) {
|
||||||
|
XGrabButton(dwn->display, Button3, Mod1Mask | lock_combos[gi], window, False,
|
||||||
|
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
|
||||||
|
GrabModeAsync, GrabModeAsync, None, None);
|
||||||
|
XGrabButton(dwn->display, Button1, Mod1Mask | lock_combos[gi], window, False,
|
||||||
|
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
|
||||||
|
GrabModeAsync, GrabModeAsync, None, None);
|
||||||
|
}
|
||||||
|
|
||||||
client_sync_log("client_manage: syncing X");
|
client_sync_log("client_manage: syncing X");
|
||||||
XSync(dwn->display, False);
|
XSync(dwn->display, False);
|
||||||
|
|
||||||
@ -905,6 +916,7 @@ void client_set_maximize(Client *client, bool maximized)
|
|||||||
client->old_y = client->y;
|
client->old_y = client->y;
|
||||||
client->old_width = client->width;
|
client->old_width = client->width;
|
||||||
client->old_height = client->height;
|
client->old_height = client->height;
|
||||||
|
client->floating_before_maximize = (client->flags & CLIENT_FLOATING) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
client->flags |= CLIENT_MAXIMIZED;
|
client->flags |= CLIENT_MAXIMIZED;
|
||||||
@ -933,6 +945,10 @@ void client_set_maximize(Client *client, bool maximized)
|
|||||||
} else {
|
} else {
|
||||||
client->flags &= ~CLIENT_MAXIMIZED;
|
client->flags &= ~CLIENT_MAXIMIZED;
|
||||||
|
|
||||||
|
if (!client->floating_before_maximize) {
|
||||||
|
client->flags &= ~CLIENT_FLOATING;
|
||||||
|
}
|
||||||
|
|
||||||
atoms_update_wm_state(client->window, ewmh.NET_WM_STATE_MAXIMIZED_VERT, false);
|
atoms_update_wm_state(client->window, ewmh.NET_WM_STATE_MAXIMIZED_VERT, false);
|
||||||
atoms_update_wm_state(client->window, ewmh.NET_WM_STATE_MAXIMIZED_HORZ, false);
|
atoms_update_wm_state(client->window, ewmh.NET_WM_STATE_MAXIMIZED_HORZ, false);
|
||||||
api_emit_window_maximized(client->window, false);
|
api_emit_window_maximized(client->window, false);
|
||||||
@ -942,8 +958,33 @@ void client_set_maximize(Client *client, bool maximized)
|
|||||||
client->width = client->old_width;
|
client->width = client->old_width;
|
||||||
client->height = client->old_height;
|
client->height = client->old_height;
|
||||||
|
|
||||||
|
if (client->width < 50) client->width = 50;
|
||||||
|
if (client->height < 50) client->height = 50;
|
||||||
|
|
||||||
|
int area_x, area_y, area_w, area_h;
|
||||||
|
layout_get_usable_area(&area_x, &area_y, &area_w, &area_h);
|
||||||
|
|
||||||
|
if (client->x + client->width > area_x + area_w) {
|
||||||
|
client->x = area_x + area_w - client->width;
|
||||||
|
}
|
||||||
|
if (client->x < area_x) {
|
||||||
|
client->x = area_x;
|
||||||
|
}
|
||||||
|
if (client->y + client->height > area_y + area_h) {
|
||||||
|
client->y = area_y + area_h - client->height;
|
||||||
|
}
|
||||||
|
if (client->y < area_y) {
|
||||||
|
client->y = area_y;
|
||||||
|
}
|
||||||
|
|
||||||
client_configure(client);
|
client_configure(client);
|
||||||
decorations_render(client, true);
|
decorations_render(client, true);
|
||||||
|
client_raise(client);
|
||||||
|
client_focus(client, true);
|
||||||
|
|
||||||
|
if (!client->floating_before_maximize) {
|
||||||
|
workspace_arrange_current();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
#define BUTTON_SIZE 16
|
#define BUTTON_SIZE 16
|
||||||
#define BUTTON_PADDING 4
|
#define BUTTON_PADDING 4
|
||||||
|
|
||||||
#define RESIZE_EDGE 8
|
#define RESIZE_EDGE 12
|
||||||
|
|
||||||
#define DEC_XFT_COLOR_CACHE_SIZE 8
|
#define DEC_XFT_COLOR_CACHE_SIZE 8
|
||||||
|
|
||||||
|
|||||||
36
src/keys.c
36
src/keys.c
@ -18,6 +18,7 @@
|
|||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "api.h"
|
#include "api.h"
|
||||||
#include "marks.h"
|
#include "marks.h"
|
||||||
|
#include "panel.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -610,6 +611,8 @@ void keys_setup_defaults(void)
|
|||||||
|
|
||||||
keys_bind(MOD_SUPER, XK_m, key_set_mark, "Set window mark");
|
keys_bind(MOD_SUPER, XK_m, key_set_mark, "Set window mark");
|
||||||
keys_bind(MOD_SUPER, XK_apostrophe, key_goto_mark, "Go to marked window");
|
keys_bind(MOD_SUPER, XK_apostrophe, key_goto_mark, "Go to marked window");
|
||||||
|
|
||||||
|
keys_bind(MOD_ALT, XK_space, key_expose_all, "Expose all windows");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -936,8 +939,11 @@ void key_show_shortcuts(void)
|
|||||||
"Alt+F9 Toggle minimize\n"
|
"Alt+F9 Toggle minimize\n"
|
||||||
"Alt+F10 Toggle maximize\n"
|
"Alt+F10 Toggle maximize\n"
|
||||||
"Alt+F11 Toggle fullscreen\n"
|
"Alt+F11 Toggle fullscreen\n"
|
||||||
|
"Alt+Space Expose all windows\n"
|
||||||
"Super+F9 Toggle floating\n"
|
"Super+F9 Toggle floating\n"
|
||||||
"Super+K Kill all applications\n"
|
"Super+K Kill all applications\n"
|
||||||
|
"Alt+Drag Move window (any position)\n"
|
||||||
|
"Alt+Right-Drag Resize window (any position)\n"
|
||||||
"\n"
|
"\n"
|
||||||
"=== Workspaces ===\n"
|
"=== Workspaces ===\n"
|
||||||
"F1-F9 Switch to workspace\n"
|
"F1-F9 Switch to workspace\n"
|
||||||
@ -1327,6 +1333,36 @@ void key_resize_window_down(void)
|
|||||||
decorations_render(c, true);
|
decorations_render(c, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void key_expose_all(void)
|
||||||
|
{
|
||||||
|
if (dwn == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dwn->desktop_shown) {
|
||||||
|
dwn->desktop_shown = false;
|
||||||
|
dwn->desktop_minimized_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Client *c = dwn->client_list; c != NULL; c = c->next) {
|
||||||
|
if (c->workspace != (unsigned int)dwn->current_workspace) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (client_is_fullscreen(c)) {
|
||||||
|
client_set_fullscreen(c, false);
|
||||||
|
}
|
||||||
|
if (client_is_maximized(c)) {
|
||||||
|
client_set_maximize(c, false);
|
||||||
|
}
|
||||||
|
if (client_is_minimized(c)) {
|
||||||
|
client_restore(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
workspace_arrange_current();
|
||||||
|
panel_render_all();
|
||||||
|
}
|
||||||
|
|
||||||
void key_set_mark(void)
|
void key_set_mark(void)
|
||||||
{
|
{
|
||||||
marks_start_set_mode();
|
marks_start_set_mode();
|
||||||
|
|||||||
106
src/main.c
106
src/main.c
@ -497,6 +497,8 @@ static void handle_leave_notify(XCrossingEvent *ev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Cursor cursor_for_direction(int direction);
|
||||||
|
|
||||||
static void handle_button_press(XButtonEvent *ev)
|
static void handle_button_press(XButtonEvent *ev)
|
||||||
{
|
{
|
||||||
if (ev == NULL || dwn == NULL || dwn->display == NULL) {
|
if (ev == NULL || dwn == NULL || dwn->display == NULL) {
|
||||||
@ -560,6 +562,50 @@ static void handle_button_press(XButtonEvent *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_client_window) {
|
if (is_client_window) {
|
||||||
|
bool alt_held = (ev->state & Mod1Mask) != 0;
|
||||||
|
|
||||||
|
if (alt_held && ev->button == Button3) {
|
||||||
|
client_focus(c, true);
|
||||||
|
int cx = c->x + c->width / 2;
|
||||||
|
int cy = c->y + c->height / 2;
|
||||||
|
int dir = 0;
|
||||||
|
if (ev->x_root < cx) dir |= RESIZE_LEFT; else dir |= RESIZE_RIGHT;
|
||||||
|
if (ev->y_root < cy) dir |= RESIZE_TOP; else dir |= RESIZE_BOTTOM;
|
||||||
|
|
||||||
|
dwn->drag_client = c;
|
||||||
|
dwn->drag_start_x = ev->x_root;
|
||||||
|
dwn->drag_start_y = ev->y_root;
|
||||||
|
dwn->drag_orig_x = c->x;
|
||||||
|
dwn->drag_orig_y = c->y;
|
||||||
|
dwn->drag_orig_w = c->width;
|
||||||
|
dwn->drag_orig_h = c->height;
|
||||||
|
dwn->resizing = true;
|
||||||
|
dwn->drag_direction = dir;
|
||||||
|
|
||||||
|
XGrabPointer(dwn->display, dwn->root, True,
|
||||||
|
PointerMotionMask | ButtonReleaseMask,
|
||||||
|
GrabModeAsync, GrabModeAsync, None,
|
||||||
|
cursor_for_direction(dir), CurrentTime);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alt_held && ev->button == Button1) {
|
||||||
|
client_focus(c, true);
|
||||||
|
dwn->drag_client = c;
|
||||||
|
dwn->drag_start_x = ev->x_root;
|
||||||
|
dwn->drag_start_y = ev->y_root;
|
||||||
|
dwn->drag_orig_x = c->x;
|
||||||
|
dwn->drag_orig_y = c->y;
|
||||||
|
dwn->resizing = false;
|
||||||
|
dwn->drag_direction = 0;
|
||||||
|
|
||||||
|
XGrabPointer(dwn->display, dwn->root, True,
|
||||||
|
PointerMotionMask | ButtonReleaseMask,
|
||||||
|
GrabModeAsync, GrabModeAsync, None,
|
||||||
|
dwn->cursor_move, CurrentTime);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
XAllowEvents(dwn->display, ReplayPointer, ev->time);
|
XAllowEvents(dwn->display, ReplayPointer, ev->time);
|
||||||
client_focus(c, true);
|
client_focus(c, true);
|
||||||
return;
|
return;
|
||||||
@ -588,7 +634,8 @@ static void handle_button_press(XButtonEvent *ev)
|
|||||||
|
|
||||||
XGrabPointer(dwn->display, c->frame, True,
|
XGrabPointer(dwn->display, c->frame, True,
|
||||||
PointerMotionMask | ButtonReleaseMask,
|
PointerMotionMask | ButtonReleaseMask,
|
||||||
GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
GrabModeAsync, GrabModeAsync, None,
|
||||||
|
dwn->cursor_move, CurrentTime);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -610,7 +657,8 @@ static void handle_button_press(XButtonEvent *ev)
|
|||||||
|
|
||||||
XGrabPointer(dwn->display, c->frame, True,
|
XGrabPointer(dwn->display, c->frame, True,
|
||||||
PointerMotionMask | ButtonReleaseMask,
|
PointerMotionMask | ButtonReleaseMask,
|
||||||
GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
GrabModeAsync, GrabModeAsync, None,
|
||||||
|
cursor_for_direction(direction), CurrentTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -645,6 +693,24 @@ static void handle_button_release(XButtonEvent *ev)
|
|||||||
api_emit_mouse_button_released(ev->button, ev->x_root, ev->y_root);
|
api_emit_mouse_button_released(ev->button, ev->x_root, ev->y_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Cursor cursor_for_direction(int direction)
|
||||||
|
{
|
||||||
|
bool left = (direction & RESIZE_LEFT) != 0;
|
||||||
|
bool right = (direction & RESIZE_RIGHT) != 0;
|
||||||
|
bool top = (direction & RESIZE_TOP) != 0;
|
||||||
|
bool bottom = (direction & RESIZE_BOTTOM) != 0;
|
||||||
|
|
||||||
|
if (top && left) return dwn->cursor_resize_top_left;
|
||||||
|
if (top && right) return dwn->cursor_resize_top_right;
|
||||||
|
if (bottom && left) return dwn->cursor_resize_bottom_left;
|
||||||
|
if (bottom && right) return dwn->cursor_resize_bottom_right;
|
||||||
|
if (left) return dwn->cursor_resize_left;
|
||||||
|
if (right) return dwn->cursor_resize_right;
|
||||||
|
if (top) return dwn->cursor_resize_top;
|
||||||
|
if (bottom) return dwn->cursor_resize_bottom;
|
||||||
|
return dwn->cursor_default;
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_motion_notify(XMotionEvent *ev)
|
static void handle_motion_notify(XMotionEvent *ev)
|
||||||
{
|
{
|
||||||
if (ev == NULL || dwn == NULL || dwn->display == NULL) {
|
if (ev == NULL || dwn == NULL || dwn->display == NULL) {
|
||||||
@ -669,6 +735,17 @@ static void handle_motion_notify(XMotionEvent *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dwn->drag_client == NULL) {
|
if (dwn->drag_client == NULL) {
|
||||||
|
Client *c = client_find_by_frame(ev->window);
|
||||||
|
if (c != NULL && c->frame != None) {
|
||||||
|
int direction = 0;
|
||||||
|
if (decorations_hit_test_resize_area(c, ev->x, ev->y, &direction)) {
|
||||||
|
XDefineCursor(dwn->display, c->frame, cursor_for_direction(direction));
|
||||||
|
} else if (decorations_hit_test_title_bar(c, ev->x, ev->y)) {
|
||||||
|
XDefineCursor(dwn->display, c->frame, dwn->cursor_move);
|
||||||
|
} else {
|
||||||
|
XDefineCursor(dwn->display, c->frame, dwn->cursor_default);
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -986,8 +1063,18 @@ int dwn_init(void)
|
|||||||
StructureNotifyMask | PropertyChangeMask |
|
StructureNotifyMask | PropertyChangeMask |
|
||||||
ButtonPressMask | PointerMotionMask);
|
ButtonPressMask | PointerMotionMask);
|
||||||
|
|
||||||
Cursor cursor = XCreateFontCursor(dwn->display, XC_left_ptr);
|
dwn->cursor_default = XCreateFontCursor(dwn->display, XC_left_ptr);
|
||||||
XDefineCursor(dwn->display, dwn->root, cursor);
|
dwn->cursor_resize_top_left = XCreateFontCursor(dwn->display, XC_top_left_corner);
|
||||||
|
dwn->cursor_resize_top_right = XCreateFontCursor(dwn->display, XC_top_right_corner);
|
||||||
|
dwn->cursor_resize_bottom_left = XCreateFontCursor(dwn->display, XC_bottom_left_corner);
|
||||||
|
dwn->cursor_resize_bottom_right = XCreateFontCursor(dwn->display, XC_bottom_right_corner);
|
||||||
|
dwn->cursor_resize_left = XCreateFontCursor(dwn->display, XC_left_side);
|
||||||
|
dwn->cursor_resize_right = XCreateFontCursor(dwn->display, XC_right_side);
|
||||||
|
dwn->cursor_resize_top = XCreateFontCursor(dwn->display, XC_top_side);
|
||||||
|
dwn->cursor_resize_bottom = XCreateFontCursor(dwn->display, XC_bottom_side);
|
||||||
|
dwn->cursor_move = XCreateFontCursor(dwn->display, XC_fleur);
|
||||||
|
|
||||||
|
XDefineCursor(dwn->display, dwn->root, dwn->cursor_default);
|
||||||
|
|
||||||
scan_existing_windows();
|
scan_existing_windows();
|
||||||
|
|
||||||
@ -1055,6 +1142,17 @@ void dwn_cleanup(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dwn->display != NULL) {
|
if (dwn->display != NULL) {
|
||||||
|
if (dwn->cursor_default) XFreeCursor(dwn->display, dwn->cursor_default);
|
||||||
|
if (dwn->cursor_resize_top_left) XFreeCursor(dwn->display, dwn->cursor_resize_top_left);
|
||||||
|
if (dwn->cursor_resize_top_right) XFreeCursor(dwn->display, dwn->cursor_resize_top_right);
|
||||||
|
if (dwn->cursor_resize_bottom_left) XFreeCursor(dwn->display, dwn->cursor_resize_bottom_left);
|
||||||
|
if (dwn->cursor_resize_bottom_right) XFreeCursor(dwn->display, dwn->cursor_resize_bottom_right);
|
||||||
|
if (dwn->cursor_resize_left) XFreeCursor(dwn->display, dwn->cursor_resize_left);
|
||||||
|
if (dwn->cursor_resize_right) XFreeCursor(dwn->display, dwn->cursor_resize_right);
|
||||||
|
if (dwn->cursor_resize_top) XFreeCursor(dwn->display, dwn->cursor_resize_top);
|
||||||
|
if (dwn->cursor_resize_bottom) XFreeCursor(dwn->display, dwn->cursor_resize_bottom);
|
||||||
|
if (dwn->cursor_move) XFreeCursor(dwn->display, dwn->cursor_move);
|
||||||
|
|
||||||
XCloseDisplay(dwn->display);
|
XCloseDisplay(dwn->display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
37
src/panel.c
37
src/panel.c
@ -405,24 +405,27 @@ void panel_render(Panel *panel)
|
|||||||
x += width + WIDGET_SPACING;
|
x += width + WIDGET_SPACING;
|
||||||
|
|
||||||
panel_render_layout_indicator(panel, x, &width);
|
panel_render_layout_indicator(panel, x, &width);
|
||||||
x += width + WIDGET_SPACING;
|
int taskbar_start = x + width + WIDGET_SPACING;
|
||||||
|
|
||||||
panel_render_taskbar(panel, x, &width);
|
|
||||||
|
|
||||||
int systray_actual_width = systray_get_width();
|
int systray_actual_width = systray_get_width();
|
||||||
int systray_x = panel->width - systray_actual_width - PANEL_PADDING;
|
int systray_x = panel->width - systray_actual_width - PANEL_PADDING;
|
||||||
|
|
||||||
/* Render fade controls before systray */
|
|
||||||
int fade_width = fade_controls_get_width();
|
int fade_width = fade_controls_get_width();
|
||||||
int fade_x = systray_x - fade_width - WIDGET_SPACING;
|
int fade_x = systray_x - fade_width - WIDGET_SPACING;
|
||||||
fade_controls_render(panel, fade_x);
|
|
||||||
|
|
||||||
systray_render(panel, systray_x, &width);
|
int ai_x = 0;
|
||||||
|
if (dwn->ai_enabled) {
|
||||||
|
int ai_width = panel_text_width("[AI]", 4);
|
||||||
|
ai_x = fade_x - ai_width - WIDGET_SPACING;
|
||||||
|
}
|
||||||
|
|
||||||
|
panel_render_taskbar(panel, taskbar_start, &width);
|
||||||
|
|
||||||
if (dwn->ai_enabled) {
|
if (dwn->ai_enabled) {
|
||||||
int ai_x = systray_x - 60;
|
|
||||||
panel_render_ai_status(panel, ai_x, &width);
|
panel_render_ai_status(panel, ai_x, &width);
|
||||||
}
|
}
|
||||||
|
fade_controls_render(panel, fade_x);
|
||||||
|
systray_render(panel, systray_x, &width);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
int date_width = 0;
|
int date_width = 0;
|
||||||
@ -535,8 +538,14 @@ void panel_render_taskbar(Panel *panel, int x, int *width)
|
|||||||
|
|
||||||
int current_x = x;
|
int current_x = x;
|
||||||
int systray_actual_width = systray_get_width();
|
int systray_actual_width = systray_get_width();
|
||||||
int ai_width = dwn->ai_enabled ? 60 : 0;
|
int fade_width = fade_controls_get_width();
|
||||||
int right_reserve = systray_actual_width + ai_width + PANEL_PADDING * 2;
|
int ai_width = 0;
|
||||||
|
if (dwn->ai_enabled) {
|
||||||
|
ai_width = panel_text_width("[AI]", 4);
|
||||||
|
}
|
||||||
|
int right_reserve = PANEL_PADDING + systray_actual_width + WIDGET_SPACING
|
||||||
|
+ fade_width + WIDGET_SPACING
|
||||||
|
+ (ai_width > 0 ? ai_width + WIDGET_SPACING : 0);
|
||||||
int available_width = panel->width - x - right_reserve;
|
int available_width = panel->width - x - right_reserve;
|
||||||
if (available_width < 0) available_width = 0;
|
if (available_width < 0) available_width = 0;
|
||||||
int item_count = 0;
|
int item_count = 0;
|
||||||
@ -790,8 +799,14 @@ Client *panel_hit_test_taskbar(Panel *panel, int x, int y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int systray_actual_width = systray_get_width();
|
int systray_actual_width = systray_get_width();
|
||||||
int ai_width = dwn->ai_enabled ? 60 : 0;
|
int fade_width = fade_controls_get_width();
|
||||||
int right_reserve = systray_actual_width + ai_width + PANEL_PADDING * 2;
|
int ai_width = 0;
|
||||||
|
if (dwn->ai_enabled) {
|
||||||
|
ai_width = panel_text_width("[AI]", 4);
|
||||||
|
}
|
||||||
|
int right_reserve = PANEL_PADDING + systray_actual_width + WIDGET_SPACING
|
||||||
|
+ fade_width + WIDGET_SPACING
|
||||||
|
+ (ai_width > 0 ? ai_width + WIDGET_SPACING : 0);
|
||||||
int available_width = panel->width - taskbar_start - right_reserve;
|
int available_width = panel->width - taskbar_start - right_reserve;
|
||||||
if (available_width < 0) available_width = 0;
|
if (available_width < 0) available_width = 0;
|
||||||
int item_count = 0;
|
int item_count = 0;
|
||||||
|
|||||||
@ -1371,21 +1371,37 @@ void fade_controls_render(Panel *panel, int x)
|
|||||||
|
|
||||||
int fade_controls_get_width(void)
|
int fade_controls_get_width(void)
|
||||||
{
|
{
|
||||||
/* Calculate approximate width for both controls */
|
float speed = config_get_fade_speed();
|
||||||
return 80; /* Approximate width for "S:0.5 I:100%" + spacing */
|
char speed_label[16];
|
||||||
|
snprintf(speed_label, sizeof(speed_label), "S:%.1f", speed);
|
||||||
|
|
||||||
|
float intensity = config_get_fade_intensity();
|
||||||
|
char intensity_label[16];
|
||||||
|
snprintf(intensity_label, sizeof(intensity_label), "I:%d%%", (int)(intensity * 100));
|
||||||
|
|
||||||
|
return get_text_width(speed_label) + SYSTRAY_SPACING + get_text_width(intensity_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fade_controls_hit_test(int x)
|
int fade_controls_hit_test(int x)
|
||||||
{
|
{
|
||||||
/* Check if x position hits any fade control icon */
|
float speed = config_get_fade_speed();
|
||||||
/* Return 1 for speed, 2 for intensity, 0 for none */
|
char speed_label[16];
|
||||||
|
snprintf(speed_label, sizeof(speed_label), "S:%.1f", speed);
|
||||||
|
int speed_width = get_text_width(speed_label);
|
||||||
|
|
||||||
if (x >= fade_speed_icon_x && x < fade_speed_icon_x + 40) {
|
if (x >= fade_speed_icon_x && x < fade_speed_icon_x + speed_width) {
|
||||||
return 1; /* Speed control */
|
return 1;
|
||||||
}
|
}
|
||||||
if (x >= fade_intensity_icon_x && x < fade_intensity_icon_x + 50) {
|
|
||||||
return 2; /* Intensity control */
|
float intensity = config_get_fade_intensity();
|
||||||
|
char intensity_label[16];
|
||||||
|
snprintf(intensity_label, sizeof(intensity_label), "I:%d%%", (int)(intensity * 100));
|
||||||
|
int intensity_width = get_text_width(intensity_label);
|
||||||
|
|
||||||
|
if (x >= fade_intensity_icon_x && x < fade_intensity_icon_x + intensity_width) {
|
||||||
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user