mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2025-10-29 05:40:21 -04:00
feat: scroller layout and alt-tab switch like gnome
Update README.md Update README.md Update README.md
This commit is contained in:
parent
f2b0d45098
commit
793bd1bd1a
3 changed files with 274 additions and 103 deletions
|
|
@ -1,8 +1,14 @@
|
|||
|
||||
Master-Stack Layout
|
||||
|
||||
https://github.com/user-attachments/assets/da80c6d1-b9a5-44c4-b738-6421365e6aa5
|
||||
|
||||
|
||||
Scroller Layout
|
||||
|
||||
https://github.com/user-attachments/assets/2ff96868-b276-4fa1-b4d7-87bdc36beb3c
|
||||
|
||||
|
||||
|
||||
# feature
|
||||
- dwl ipc support
|
||||
|
|
@ -29,6 +35,8 @@ https://github.com/user-attachments/assets/da80c6d1-b9a5-44c4-b738-6421365e6aa5
|
|||
- window close animaition
|
||||
- custom mov/open/tag animaition sppeed
|
||||
- fade in animation
|
||||
- alt-tab switch window like gnome
|
||||
- niri like scroller layout
|
||||
|
||||
|
||||
## suggest tools
|
||||
|
|
|
|||
61
config.def.h
61
config.def.h
|
|
@ -17,43 +17,54 @@ static const uint32_t animation_duration_tag = 300; // Animation tag speed
|
|||
// static const double animation_curve[4] = {0.05,0.9,0.1,1.05}; // Animation curve
|
||||
static const double animation_curve[4] = {0.46,1.0,0.29,0.99}; // Animation curve
|
||||
|
||||
/* appearance */
|
||||
static const unsigned int axis_bind_apply_timeout = 100; // Timeout for wheel binding actions
|
||||
static const unsigned int focus_on_activate = 1; // Automatically focus on window activation request
|
||||
/* scroller layout setting*/
|
||||
static const int scroller_structs = 20;
|
||||
static const float scroller_default_proportion = 0.8;
|
||||
static bool scoller_foucs_center = false;
|
||||
static const float scroller_proportion_preset[] = {0.5,0.8,1.0};
|
||||
|
||||
/* master-stack layout setting*/
|
||||
static const unsigned int new_is_master = 1; // New windows are inserted at the head
|
||||
static const unsigned int default_mfact = 0.55f; // Master mfact
|
||||
static const unsigned int default_nmaster = 1; // Master number
|
||||
/* logging */
|
||||
static int log_level = WLR_ERROR;
|
||||
static const unsigned int numlockon = 1; // Enable numlock
|
||||
|
||||
/* overview setting*/
|
||||
static const unsigned int hotarea_size = 10; // Hot area size, 10x10
|
||||
static const unsigned int enable_hotarea = 1; // Enable mouse hot area
|
||||
static const unsigned int ov_tab_mode = 1; // Enable switch window like gnome alt+tab
|
||||
static int smartgaps = 0; /* 1 means no outer gap when there is only one window */
|
||||
static const int overviewgappi = 5; /* Gap between windows and edges in overview mode */
|
||||
static const int overviewgappo = 30; /* Gap between windows in overview mode */
|
||||
|
||||
/* misc */
|
||||
static const unsigned int axis_bind_apply_timeout = 100; // Timeout for wheel binding actions
|
||||
static const unsigned int focus_on_activate = 1; // Automatically focus on window activation request
|
||||
static const unsigned int numlockon = 1; // Enable numlock
|
||||
static int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if the surface isn't visible */
|
||||
static int sloppyfocus = 1; /* Focus follows mouse */
|
||||
static int warpcursor = 1; /* Warp cursor to focused client */
|
||||
|
||||
/* logging */
|
||||
static int log_level = WLR_ERROR;
|
||||
|
||||
/* appearance */
|
||||
static int smartgaps = 0; /* 1 means no outer gap when there is only one window */
|
||||
static unsigned int gappih = 5; /* Horizontal inner gap between windows */
|
||||
static unsigned int gappiv = 5; /* Vertical inner gap between windows */
|
||||
static unsigned int gappoh = 10; /* Horizontal outer gap between windows and screen edge */
|
||||
static unsigned int gappov = 10; /* Vertical outer gap between windows and screen edge */
|
||||
static int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if the surface isn't visible */
|
||||
static unsigned int borderpx = 5; /* Border pixel of windows */
|
||||
static const float rootcolor[] = COLOR(0x323232ff);
|
||||
static const float bordercolor[] = COLOR(0x444444ff);
|
||||
static const float focuscolor[] = COLOR(0xad741fff);
|
||||
static const float fakefullscreencolor[] = COLOR(0x89aa61ff);
|
||||
static const float maxmizescreencolor[] = COLOR(0x89aa61ff);
|
||||
static const float urgentcolor[] = COLOR(0xad401fff);
|
||||
static const float scratchpadcolor[] = COLOR(0x516c93ff);
|
||||
static const float globalcolor[] = COLOR(0xb153a7ff);
|
||||
// static const char *cursor_theme = "Bibata-Modern-Ice";
|
||||
|
||||
static const int overviewgappi = 5; /* Gap between windows and edges in overview mode */
|
||||
static const int overviewgappo = 30; /* Gap between windows in overview mode */
|
||||
|
||||
/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
|
||||
static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0};
|
||||
|
||||
static int warpcursor = 1; /* Warp cursor to focused client */
|
||||
|
||||
/* Autostart */
|
||||
static const char *const autostart[] = {
|
||||
"/bin/sh",
|
||||
|
|
@ -94,8 +105,8 @@ static const Layout overviewlayout = { "", overview };
|
|||
|
||||
static const Layout layouts[] = { // At least two layouts, cannot delete less than two
|
||||
/* symbol arrange function */
|
||||
{ "", tile }, // Stack layout
|
||||
{ "", grid }, // Grid layout
|
||||
{ "", tile, "tile" }, // master-stack layout
|
||||
{ "", scroller, "scroller" }, // scroller layout
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -178,14 +189,14 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
|
|||
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||
|
||||
/* commands */
|
||||
// static const char *termcmd[] = { "foot", NULL };
|
||||
// static const char *menucmd[] = { "wofi --conf ~/.config/maomao/wofi/config_menu", NULL };
|
||||
static const char *termcmd[] = { "foot", NULL };
|
||||
static const char *menucmd[] = { "wofi", NULL };
|
||||
|
||||
static const Key keys[] = {
|
||||
/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
|
||||
/* modifier key function argument */
|
||||
{ MODKEY, XKB_KEY_space, spawn, SHCMD("wofi") },
|
||||
{ MODKEY, XKB_KEY_Return, spawn, SHCMD("foot") },
|
||||
{ MODKEY, XKB_KEY_space, spawn, {.v = menucmd} },
|
||||
{ MODKEY, XKB_KEY_Return, spawn, {.v = termcmd} },
|
||||
|
||||
|
||||
{ WLR_MODIFIER_LOGO, XKB_KEY_Tab, focusstack, {.i = +1} },
|
||||
|
|
@ -214,11 +225,13 @@ static const Key keys[] = {
|
|||
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_LOGO, XKB_KEY_Left, tagtoleft, {0} }, /* ctrl alt left | Move current window to the left tag */
|
||||
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_LOGO, XKB_KEY_Right, tagtoright, {0} },
|
||||
{ MODKEY, XKB_KEY_q, killclient, {0} },
|
||||
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_LOGO, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
|
||||
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_LOGO, XKB_KEY_g, setlayout, {.v = &layouts[1]} },
|
||||
{ MODKEY, XKB_KEY_e, set_proportion, {.f = 1.0} }, /* set scroller layout window to maxsize */
|
||||
{ MODKEY, XKB_KEY_w, switch_proportion_preset, {0}}, /* switch scroller layout window to preset size */
|
||||
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_LOGO, XKB_KEY_i, setlayout, {.v = &layouts[0]} },
|
||||
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_LOGO, XKB_KEY_l, setlayout, {.v = &layouts[1]} },
|
||||
{ WLR_MODIFIER_LOGO, XKB_KEY_n, switch_layout, {0} },
|
||||
{ WLR_MODIFIER_ALT, XKB_KEY_backslash, togglefloating, {0} },
|
||||
{ MODKEY, XKB_KEY_a, togglefakefullscreen, {0} },
|
||||
{ MODKEY, XKB_KEY_a, togglemaxmizescreen, {0} },
|
||||
{ MODKEY, XKB_KEY_f, togglefullscreen, {0} },
|
||||
{ WLR_MODIFIER_LOGO, XKB_KEY_i, minized, {0} }, // Minimize, move to scratchpad
|
||||
{ WLR_MODIFIER_LOGO|WLR_MODIFIER_SHIFT, XKB_KEY_I, restore_minized, {0} },
|
||||
|
|
@ -250,7 +263,7 @@ static const Key keys[] = {
|
|||
|
||||
static const Button buttons[] = {
|
||||
{ WLR_MODIFIER_LOGO, BTN_LEFT, moveresize, {.ui = CurMove } },
|
||||
{ 0, BTN_MIDDLE, togglefakefullscreen, {0} }, // Middle button triggers fake fullscreen
|
||||
{ 0, BTN_MIDDLE, togglemaxmizescreen, {0} }, // Middle button triggers fake fullscreen
|
||||
{ WLR_MODIFIER_LOGO, BTN_RIGHT, moveresize, {.ui = CurResize } },
|
||||
{ WLR_MODIFIER_ALT|WLR_MODIFIER_CTRL, BTN_LEFT, spawn, SHCMD("bash ~/tool/shotTranslate.sh shot")},
|
||||
{ 0, BTN_LEFT, toggleoverview, {.i = -1 } },
|
||||
|
|
|
|||
308
main.c
308
main.c
|
|
@ -84,8 +84,8 @@
|
|||
#define TAGMASK ((1 << LENGTH(tags)) - 1)
|
||||
#define LISTEN(E, L, H) wl_signal_add((E), ((L)->notify = (H), (L)))
|
||||
#define ISFULLSCREEN(A) \
|
||||
((A)->isfullscreen || (A)->isfakefullscreen || \
|
||||
(A)->overview_isfakefullscreenbak || (A)->overview_isfullscreenbak)
|
||||
((A)->isfullscreen || (A)->ismaxmizescreen || \
|
||||
(A)->overview_ismaxmizescreenbak || (A)->overview_isfullscreenbak)
|
||||
#define LISTEN_STATIC(E, H) \
|
||||
do { \
|
||||
static struct wl_listener _l = {.notify = (H)}; \
|
||||
|
|
@ -197,12 +197,12 @@ typedef struct {
|
|||
uint32_t configure_serial;
|
||||
struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel;
|
||||
int isfloating, isurgent, isfullscreen, istiled, isminied;
|
||||
int isfakefullscreen;
|
||||
int ismaxmizescreen;
|
||||
int overview_backup_x, overview_backup_y, overview_backup_w,
|
||||
overview_backup_h, overview_backup_bw;
|
||||
int fullscreen_backup_x, fullscreen_backup_y, fullscreen_backup_w,
|
||||
fullscreen_backup_h;
|
||||
int overview_isfullscreenbak, overview_isfakefullscreenbak,
|
||||
int overview_isfullscreenbak, overview_ismaxmizescreenbak,
|
||||
overview_isfloatingbak;
|
||||
uint32_t resize; /* configure serial of a pending resize */
|
||||
|
||||
|
|
@ -225,6 +225,7 @@ typedef struct {
|
|||
bool resizing;
|
||||
bool is_open_animation;
|
||||
bool is_restoring_from_ov;
|
||||
float scroller_proportion;
|
||||
|
||||
struct dwl_animation animation;
|
||||
|
||||
|
|
@ -278,6 +279,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
const char *symbol;
|
||||
void (*arrange)(Monitor *, unsigned int, unsigned int);
|
||||
const char *name;
|
||||
} Layout;
|
||||
|
||||
struct Monitor {
|
||||
|
|
@ -307,7 +309,7 @@ struct Monitor {
|
|||
int gappoh; /* horizontal outer gaps */
|
||||
int gappov; /* vertical outer gaps */
|
||||
Pertag *pertag;
|
||||
Client *sel;
|
||||
Client *sel,*prevsel;
|
||||
int isoverview;
|
||||
int is_in_hotarea;
|
||||
int gamma_lut_changed;
|
||||
|
|
@ -480,7 +482,7 @@ static void run(char *startup_cmd);
|
|||
static void setcursor(struct wl_listener *listener, void *data);
|
||||
static void setfloating(Client *c, int floating);
|
||||
static void setfullscreen(Client *c, int fullscreen);
|
||||
static void setfakefullscreen(Client *c, int fakefullscreen);
|
||||
static void setmaxmizescreen(Client *c, int maxmizescreen);
|
||||
static void setgaps(int oh, int ov, int ih, int iv);
|
||||
static void setlayout(const Arg *arg);
|
||||
static void switch_layout(const Arg *arg);
|
||||
|
|
@ -498,9 +500,10 @@ static void setgamma(struct wl_listener *listener, void *data);
|
|||
static void tile(Monitor *m, unsigned int gappo, unsigned int uappi);
|
||||
static void overview(Monitor *m, unsigned int gappo, unsigned int gappi);
|
||||
static void grid(Monitor *m, unsigned int gappo, unsigned int uappi);
|
||||
static void scroller(Monitor *m, unsigned int gappo, unsigned int uappi);
|
||||
static void togglefloating(const Arg *arg);
|
||||
static void togglefullscreen(const Arg *arg);
|
||||
static void togglefakefullscreen(const Arg *arg);
|
||||
static void togglemaxmizescreen(const Arg *arg);
|
||||
static void togglegaps(const Arg *arg);
|
||||
static void toggletag(const Arg *arg);
|
||||
static void toggleview(const Arg *arg);
|
||||
|
|
@ -530,6 +533,8 @@ static void clear_fullscreen_flag(Client *c);
|
|||
static Client *direction_select(const Arg *arg);
|
||||
static void focusdir(const Arg *arg);
|
||||
static void toggleoverview(const Arg *arg);
|
||||
static void set_proportion(const Arg *arg);
|
||||
static void switch_proportion_preset(const Arg *arg);
|
||||
static void warp_cursor_to_selmon(const Monitor *m);
|
||||
unsigned int want_restore_fullscreen(Client *target_client);
|
||||
static void overview_restore(Client *c, const Arg *arg);
|
||||
|
|
@ -856,10 +861,10 @@ applybounds(Client *c, struct wlr_box *bbox) {
|
|||
|
||||
/*清除全屏标志,还原全屏时清0的border*/
|
||||
void clear_fullscreen_flag(Client *c) {
|
||||
if (c->isfullscreen || c->isfakefullscreen) {
|
||||
if (c->isfullscreen || c->ismaxmizescreen) {
|
||||
c->isfullscreen = 0;
|
||||
c->isfloating = 0;
|
||||
c->isfakefullscreen = 0;
|
||||
c->ismaxmizescreen = 0;
|
||||
c->bw = borderpx;
|
||||
client_set_fullscreen(c, false);
|
||||
}
|
||||
|
|
@ -906,9 +911,9 @@ void restore_minized(const Arg *arg) {
|
|||
|
||||
void show_scratchpad(Client *c) {
|
||||
c->is_scratchpad_show = 1;
|
||||
if (c->isfullscreen || c->isfakefullscreen) {
|
||||
if (c->isfullscreen || c->ismaxmizescreen) {
|
||||
c->isfullscreen = 0; // 清除窗口全屏标志
|
||||
c->isfakefullscreen = 0;
|
||||
c->ismaxmizescreen = 0;
|
||||
c->bw = borderpx; // 恢复非全屏的border
|
||||
}
|
||||
/* return if fullscreen */
|
||||
|
|
@ -1046,7 +1051,7 @@ void logtofile(const char *fmt, ...) {
|
|||
/* function implementations */
|
||||
void lognumtofile(unsigned int num) {
|
||||
char cmd[256];
|
||||
sprintf(cmd, "echo '%x' >> ~/log", num);
|
||||
sprintf(cmd, "echo '%d' >> ~/log", num);
|
||||
system(cmd);
|
||||
}
|
||||
|
||||
|
|
@ -1146,10 +1151,7 @@ arrange(Monitor *m, bool want_animation) {
|
|||
wl_list_for_each(c, &clients, link) {
|
||||
if (c->iskilling)
|
||||
continue;
|
||||
if (c->mon == m && c->isglobal) {
|
||||
c->tags = m->tagset[m->seltags];
|
||||
focusclient(c, 1);
|
||||
}
|
||||
|
||||
if (c->mon == m) {
|
||||
if (VISIBLEON(c, m)) {
|
||||
wlr_scene_node_set_enabled(&c->scene->node, true);
|
||||
|
|
@ -1166,7 +1168,7 @@ arrange(Monitor *m, bool want_animation) {
|
|||
}
|
||||
|
||||
c->animation.from_rule = false;
|
||||
if ((c->isfloating || c->isfullscreen || c->isfakefullscreen) &&
|
||||
if ((c->isfloating || c->isfullscreen || c->ismaxmizescreen) &&
|
||||
(c->animation.tagouting || c->animation.tagouted)) {
|
||||
c->animation.tagouting = false;
|
||||
c->animation.tagouted = false;
|
||||
|
|
@ -1247,7 +1249,7 @@ Client *direction_select(const Arg *arg) {
|
|||
return NULL;
|
||||
|
||||
if (tc &&
|
||||
(tc->isfullscreen || tc->isfakefullscreen)) /* no support for focusstack
|
||||
(tc->isfullscreen || tc->ismaxmizescreen)) /* no support for focusstack
|
||||
with fullscreen windows */
|
||||
return NULL;
|
||||
|
||||
|
|
@ -2548,8 +2550,15 @@ void focusclient(Client *c, int lift) {
|
|||
wlr_foreign_toplevel_handle_v1_set_activated(selmon->sel->foreign_toplevel,
|
||||
false);
|
||||
}
|
||||
if (selmon)
|
||||
if (selmon) {
|
||||
selmon->prevsel = selmon->sel;
|
||||
selmon->sel = c;
|
||||
if (c && selmon->prevsel && selmon->prevsel->istiled && selmon->prevsel->tags == c->tags && c->istiled && !c->isfloating && !c->isfullscreen && strcmp(selmon->lt[selmon->sellt]->name , "scroller") == 0) {
|
||||
arrange(selmon,false);
|
||||
} else if (selmon->prevsel) {
|
||||
selmon->prevsel =NULL;
|
||||
}
|
||||
}
|
||||
if (c && c->foreign_toplevel)
|
||||
wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true);
|
||||
|
||||
|
|
@ -2977,22 +2986,23 @@ mapnotify(struct wl_listener *listener, void *data) {
|
|||
WLR_EDGE_RIGHT);
|
||||
c->geom.width += 2 * c->bw;
|
||||
c->geom.height += 2 * c->bw;
|
||||
c->isfakefullscreen = 0;
|
||||
c->ismaxmizescreen = 0;
|
||||
c->isfullscreen = 0;
|
||||
c->istiled = 0;
|
||||
c->ignore_clear_fullscreen = 0;
|
||||
c->iskilling = 0;
|
||||
// c->animainit_geom.width = c->geom.width * zoom_initial_ratio;
|
||||
// c->animainit_geom.height = c->geom.height * zoom_initial_ratio;
|
||||
// c->animainit_geom.x = c->geom.x + (c->geom.width -
|
||||
// c->animainit_geom.width)/2; c->animainit_geom.y = c->geom.y +
|
||||
// (c->geom.height - c->animainit_geom.height)/2;
|
||||
c->scroller_proportion = scroller_default_proportion;
|
||||
c->is_open_animation = true;
|
||||
// nop
|
||||
if (new_is_master)
|
||||
if (new_is_master && strcmp(selmon->lt[selmon->sellt]->name , "scroller") != 0)
|
||||
// tile at the top
|
||||
wl_list_insert(&clients, &c->link); // 新窗口是master,头部入栈
|
||||
else
|
||||
else if (strcmp(selmon->lt[selmon->sellt]->name , "scroller") == 0 && selmon->sel && selmon->sel->istiled) {
|
||||
selmon->sel->link.next->prev = &c->link;
|
||||
c->link.prev = &selmon->sel->link;
|
||||
c->link.next = selmon->sel->link.next;
|
||||
selmon->sel->link.next = &c->link;
|
||||
}else
|
||||
wl_list_insert(clients.prev, &c->link); // 尾部入栈
|
||||
wl_list_insert(&fstack, &c->flink);
|
||||
|
||||
|
|
@ -3060,16 +3070,16 @@ maximizenotify(struct wl_listener *listener, void *data) {
|
|||
// if (wl_resource_get_version(c->surface.xdg->toplevel->resource)
|
||||
// < XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION)
|
||||
// wlr_xdg_surface_schedule_configure(c->surface.xdg);
|
||||
// togglefakefullscreen(&(Arg){0});
|
||||
// togglemaxmizescreen(&(Arg){0});
|
||||
Client *c = wl_container_of(listener, c, maximize);
|
||||
|
||||
if(!c || c->iskilling)
|
||||
return;
|
||||
|
||||
if (c->isfakefullscreen || c->isfullscreen)
|
||||
setfakefullscreen(c, 0);
|
||||
if (c->ismaxmizescreen || c->isfullscreen)
|
||||
setmaxmizescreen(c, 0);
|
||||
else
|
||||
setfakefullscreen(c, 1);
|
||||
setmaxmizescreen(c, 1);
|
||||
}
|
||||
|
||||
void set_minized(Client *c) {
|
||||
|
|
@ -3105,7 +3115,7 @@ minimizenotify(struct wl_listener *listener, void *data) {
|
|||
// if (wl_resource_get_version(c->surface.xdg->toplevel->resource)
|
||||
// < XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION)
|
||||
// wlr_xdg_surface_schedule_configure(c->surface.xdg);
|
||||
// togglefakefullscreen(&(Arg){0});
|
||||
// togglemaxmizescreen(&(Arg){0});
|
||||
Client *c = wl_container_of(listener, c, minimize);
|
||||
|
||||
if(!c || c->iskilling)
|
||||
|
|
@ -3466,7 +3476,7 @@ void client_handle_opacity(Client *c) {
|
|||
if (!c || !c->mon || !client_surface(c)->mapped)
|
||||
return;
|
||||
|
||||
double opacity = c->isfullscreen || c->isfakefullscreen ? 1.0
|
||||
double opacity = c->isfullscreen || c->ismaxmizescreen ? 1.0
|
||||
: c == selmon->sel ? 0.8
|
||||
: 0.5;
|
||||
|
||||
|
|
@ -3589,9 +3599,9 @@ void setborder_color(Client *c) {
|
|||
} else if (c->isglobal && c == selmon->sel) {
|
||||
for (i = 0; i < 4; i++)
|
||||
wlr_scene_rect_set_color(c->border[i], globalcolor);
|
||||
} else if (c->isfakefullscreen && c == selmon->sel) {
|
||||
} else if (c->ismaxmizescreen && c == selmon->sel) {
|
||||
for (i = 0; i < 4; i++)
|
||||
wlr_scene_rect_set_color(c->border[i], fakefullscreencolor);
|
||||
wlr_scene_rect_set_color(c->border[i], maxmizescreencolor);
|
||||
} else if (c == selmon->sel) {
|
||||
for (i = 0; i < 4; i++)
|
||||
wlr_scene_rect_set_color(c->border[i], focuscolor);
|
||||
|
|
@ -3649,7 +3659,7 @@ void exchange_two_client(Client *c1, Client *c2) {
|
|||
|
||||
void exchange_client(const Arg *arg) {
|
||||
Client *c = selmon->sel;
|
||||
if (!c || c->isfloating || c->isfullscreen || c->isfakefullscreen)
|
||||
if (!c || c->isfloating || c->isfullscreen || c->ismaxmizescreen)
|
||||
return;
|
||||
exchange_two_client(c, direction_select(arg));
|
||||
}
|
||||
|
|
@ -3664,7 +3674,9 @@ int is_special_animaiton_rule(Client *c) {
|
|||
}
|
||||
}
|
||||
|
||||
if (visible_client_number < 2 && !c->isfloating) {
|
||||
if (strcmp(selmon->lt[selmon->sellt]->name , "scroller") == 0) {
|
||||
return DOWN;
|
||||
} else if (visible_client_number < 2 && !c->isfloating) {
|
||||
return DOWN;
|
||||
} else if (visible_client_number == 2 && !c->isfloating && !new_is_master) {
|
||||
return RIGHT;
|
||||
|
|
@ -3747,19 +3759,24 @@ void resize(Client *c, struct wlr_box geo, int interact) {
|
|||
if (!c || !c->mon || !client_surface(c)->mapped)
|
||||
return;
|
||||
|
||||
struct wlr_box *bbox, oldgeom;
|
||||
struct wlr_box *bbox;
|
||||
// struct wlr_box clip;
|
||||
|
||||
if (!c->mon)
|
||||
return;
|
||||
oldgeom = c->geom;
|
||||
// oldgeom = c->geom;
|
||||
bbox = interact ? &sgeom : &c->mon->w;
|
||||
client_set_bounds(
|
||||
c, geo.width,
|
||||
geo.height); // 去掉这个推荐的窗口大小,因为有时推荐的窗口特别大导致平铺异常
|
||||
c->geom = geo;
|
||||
applybounds(
|
||||
c, bbox); // 去掉这个推荐的窗口大小,因为有时推荐的窗口特别大导致平铺异常
|
||||
|
||||
if(strcmp(c->mon->lt[c->mon->sellt]->name , "scroller") == 0) {
|
||||
c->geom = geo;
|
||||
} else { // 这里会限制不允许窗口划出屏幕
|
||||
client_set_bounds(
|
||||
c, geo.width,
|
||||
geo.height); // 去掉这个推荐的窗口大小,因为有时推荐的窗口特别大导致平铺异常
|
||||
c->geom = geo;
|
||||
applybounds(
|
||||
c, bbox); // 去掉这个推荐的窗口大小,因为有时推荐的窗口特别大导致平铺异常
|
||||
}
|
||||
|
||||
if (!c->is_open_animation) {
|
||||
c->animation.begin_fade_in = false;
|
||||
|
|
@ -3780,9 +3797,9 @@ void resize(Client *c, struct wlr_box geo, int interact) {
|
|||
if (c->animation.tagouting) {
|
||||
c->animainit_geom = c->geom;
|
||||
} else if (c->animation.tagining) {
|
||||
c->animainit_geom.height = oldgeom.height;
|
||||
c->animainit_geom.width = oldgeom.width;
|
||||
c->animainit_geom.y = oldgeom.y;
|
||||
c->animainit_geom.height = c->animation.current.height;
|
||||
c->animainit_geom.width = c->animation.current.width;
|
||||
c->animainit_geom.y = c->animation.current.y;
|
||||
} else if (c->is_open_animation) {
|
||||
set_open_animaiton(c, c->geom);
|
||||
} else {
|
||||
|
|
@ -3928,20 +3945,20 @@ setfloating(Client *c, int floating) {
|
|||
printstatus();
|
||||
}
|
||||
|
||||
void setfakefullscreen(Client *c, int fakefullscreen) {
|
||||
struct wlr_box fakefullscreen_box;
|
||||
void setmaxmizescreen(Client *c, int maxmizescreen) {
|
||||
struct wlr_box maxmizescreen_box;
|
||||
if (!c || !c->mon || !client_surface(c)->mapped || c->iskilling)
|
||||
return;
|
||||
|
||||
c->isfakefullscreen = fakefullscreen;
|
||||
c->ismaxmizescreen = maxmizescreen;
|
||||
|
||||
// c->bw = fullscreen ? 0 : borderpx;
|
||||
// client_set_fullscreen(c, fakefullscreen);
|
||||
wlr_scene_node_reparent(&c->scene->node, layers[fakefullscreen ? LyrTile
|
||||
// client_set_fullscreen(c, maxmizescreen);
|
||||
wlr_scene_node_reparent(&c->scene->node, layers[maxmizescreen ? LyrTile
|
||||
: c->isfloating ? LyrFloat
|
||||
: LyrTile]);
|
||||
|
||||
if (fakefullscreen) {
|
||||
if (maxmizescreen) {
|
||||
if (c->isfloating)
|
||||
c->oldgeom = c->geom;
|
||||
if (selmon->isoverview) {
|
||||
|
|
@ -3950,20 +3967,20 @@ void setfakefullscreen(Client *c, int fakefullscreen) {
|
|||
}
|
||||
|
||||
c->prev = c->geom;
|
||||
fakefullscreen_box.x = c->mon->w.x + gappov;
|
||||
fakefullscreen_box.y = c->mon->w.y + gappoh;
|
||||
fakefullscreen_box.width = c->mon->w.width - 2 * gappov;
|
||||
fakefullscreen_box.height = c->mon->w.height - 2 * gappov;
|
||||
maxmizescreen_box.x = c->mon->w.x + gappov;
|
||||
maxmizescreen_box.y = c->mon->w.y + gappoh;
|
||||
maxmizescreen_box.width = c->mon->w.width - 2 * gappov;
|
||||
maxmizescreen_box.height = c->mon->w.height - 2 * gappov;
|
||||
wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层
|
||||
resize(c, fakefullscreen_box, 0);
|
||||
c->isfakefullscreen = 1;
|
||||
resize(c, maxmizescreen_box, 0);
|
||||
c->ismaxmizescreen = 1;
|
||||
// c->isfloating = 0;
|
||||
} else {
|
||||
/* restore previous size instead of arrange for floating windows since
|
||||
* client positions are set by the user and cannot be recalculated */
|
||||
// resize(c, c->prev, 0);
|
||||
c->bw = borderpx;
|
||||
c->isfakefullscreen = 0;
|
||||
c->ismaxmizescreen = 0;
|
||||
c->isfullscreen = 0;
|
||||
client_set_fullscreen(c, false);
|
||||
if (c->isfloating)
|
||||
|
|
@ -4004,7 +4021,7 @@ void setfullscreen(Client *c, int fullscreen) // 用自定义全屏代理自带
|
|||
c->bw = borderpx;
|
||||
c->isfullscreen = 0;
|
||||
c->isfullscreen = 0;
|
||||
c->isfakefullscreen = 0;
|
||||
c->ismaxmizescreen = 0;
|
||||
if (c->isfloating)
|
||||
setfloating(c, 1);
|
||||
arrange(c->mon, false);
|
||||
|
|
@ -4564,6 +4581,93 @@ void grid(Monitor *m, unsigned int gappo, unsigned int gappi) {
|
|||
}
|
||||
}
|
||||
|
||||
// // 网格布局窗口大小和位置计算
|
||||
void scroller(Monitor *m, unsigned int gappo, unsigned int gappi) {
|
||||
unsigned int i, n;
|
||||
|
||||
Client *c,*root_client;
|
||||
Client *tempClients[100];
|
||||
n = 0;
|
||||
struct wlr_box target_geom;
|
||||
int focus_client_index = 0;
|
||||
bool need_scroller = false;
|
||||
|
||||
unsigned int max_client_width = m->w.width - 2 * scroller_structs - gappih;
|
||||
|
||||
wl_list_for_each(c, &clients,
|
||||
link) if (VISIBLEON(c, c->mon) && !c->isfloating && !c->iskilling &&
|
||||
!c->animation.tagouting && c->mon == selmon) {
|
||||
tempClients[n] = c;
|
||||
n++;
|
||||
}
|
||||
tempClients[n] = NULL;
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
if (n == 1) {
|
||||
c = tempClients[0];
|
||||
target_geom.height = m->w.height - 2 * gappov;
|
||||
target_geom.width = max_client_width * c->scroller_proportion;
|
||||
target_geom.x = m->w.x + (m->w.width - target_geom.width) / 2;
|
||||
target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2;
|
||||
resizeclient(c,target_geom.x,target_geom.y,target_geom.width,target_geom.height,0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(selmon->sel && selmon->sel->istiled ) {
|
||||
root_client = selmon->sel;
|
||||
} else if(selmon->prevsel && selmon->prevsel->istiled ) {
|
||||
root_client = selmon->prevsel;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0;tempClients[i]; i++) {
|
||||
c = tempClients[i];
|
||||
if (root_client == c) {
|
||||
if(selmon->prevsel != NULL && (c->geom.x - m->w.x - scroller_structs) > 0 &&
|
||||
c->geom.x + c->geom.width < m->w.x + m->w.width - scroller_structs) {
|
||||
need_scroller = false;
|
||||
}else {
|
||||
need_scroller = true;
|
||||
}
|
||||
focus_client_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
target_geom.height = m->w.height - 2 * gappov;
|
||||
target_geom.width = max_client_width* c->scroller_proportion;
|
||||
target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2;
|
||||
|
||||
if(need_scroller) {
|
||||
if (scoller_foucs_center ||
|
||||
selmon->prevsel == NULL ||
|
||||
(selmon->prevsel->scroller_proportion* max_client_width) + (root_client->scroller_proportion*max_client_width) > m->w.width - 2 * scroller_structs - gappih) {
|
||||
target_geom.x = m->w.x + (m->w.width - target_geom.width) / 2;
|
||||
|
||||
} else {
|
||||
target_geom.x = root_client->geom.x > m->w.x + (m->w.width)/2 ?
|
||||
m->w.x + (m->w.width - root_client->scroller_proportion*max_client_width -scroller_structs) :
|
||||
m->w.x + scroller_structs;
|
||||
}
|
||||
resize(tempClients[focus_client_index], target_geom, 0);
|
||||
} else {
|
||||
target_geom.x = c->geom.x;
|
||||
resize(tempClients[focus_client_index], target_geom, 0);
|
||||
}
|
||||
for (i = 1; i <= focus_client_index; i++) {
|
||||
c = tempClients[focus_client_index - i];
|
||||
target_geom.x = tempClients[focus_client_index - i + 1]->geom.x - gappih - target_geom.width;
|
||||
resize(c, target_geom, 0);
|
||||
}
|
||||
for (i = 1; tempClients[focus_client_index + i]; i++) {
|
||||
c = tempClients[focus_client_index + i];
|
||||
target_geom.x = tempClients[focus_client_index + i - 1]->geom.x + gappih + tempClients[focus_client_index + i - 1]->geom.width;
|
||||
resize(c, target_geom, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// 目标窗口有其他窗口和它同个tag就返回0
|
||||
unsigned int want_restore_fullscreen(Client *target_client) {
|
||||
Client *c = NULL;
|
||||
|
|
@ -4581,7 +4685,7 @@ unsigned int want_restore_fullscreen(Client *target_client) {
|
|||
void overview_backup(Client *c) {
|
||||
c->overview_isfloatingbak = c->isfloating;
|
||||
c->overview_isfullscreenbak = c->isfullscreen;
|
||||
c->overview_isfakefullscreenbak = c->isfakefullscreen;
|
||||
c->overview_ismaxmizescreenbak = c->ismaxmizescreen;
|
||||
c->overview_isfullscreenbak = c->isfullscreen;
|
||||
c->overview_backup_x = c->geom.x;
|
||||
c->overview_backup_y = c->geom.y;
|
||||
|
|
@ -4591,13 +4695,13 @@ void overview_backup(Client *c) {
|
|||
if (c->isfloating) {
|
||||
c->isfloating = 0;
|
||||
}
|
||||
if (c->isfullscreen || c->isfakefullscreen) {
|
||||
if (c->isfullscreen || c->ismaxmizescreen) {
|
||||
// if (c->bw == 0) { // 真全屏窗口清除x11全屏属性
|
||||
// XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
|
||||
// PropModeReplace, (unsigned char *)0, 0);
|
||||
// }
|
||||
c->isfullscreen = 0; // 清除窗口全屏标志
|
||||
c->isfakefullscreen = 0;
|
||||
c->ismaxmizescreen = 0;
|
||||
}
|
||||
c->bw = borderpx; // 恢复非全屏的border
|
||||
}
|
||||
|
|
@ -4606,24 +4710,24 @@ void overview_backup(Client *c) {
|
|||
void overview_restore(Client *c, const Arg *arg) {
|
||||
c->isfloating = c->overview_isfloatingbak;
|
||||
c->isfullscreen = c->overview_isfullscreenbak;
|
||||
c->isfakefullscreen = c->overview_isfakefullscreenbak;
|
||||
c->ismaxmizescreen = c->overview_ismaxmizescreenbak;
|
||||
c->overview_isfloatingbak = 0;
|
||||
c->overview_isfullscreenbak = 0;
|
||||
c->overview_isfakefullscreenbak = 0;
|
||||
c->overview_ismaxmizescreenbak = 0;
|
||||
c->bw = c->overview_backup_bw;
|
||||
c->is_restoring_from_ov = (arg->ui & c->tags & TAGMASK) == 0 ? true : false;
|
||||
if (c->isfloating) {
|
||||
// XRaiseWindow(dpy, c->win); // 提升悬浮窗口到顶层
|
||||
resizeclient(c, c->overview_backup_x, c->overview_backup_y,
|
||||
c->overview_backup_w, c->overview_backup_h, 1);
|
||||
} else if (c->isfullscreen || c->isfakefullscreen) {
|
||||
} else if (c->isfullscreen || c->ismaxmizescreen) {
|
||||
if (want_restore_fullscreen(
|
||||
c)) { // 如果同tag有其他窗口,且其他窗口是将要聚焦的,那么不恢复该窗口的全屏状态
|
||||
resizeclient(c, c->overview_backup_x, c->overview_backup_y,
|
||||
c->overview_backup_w, c->overview_backup_h, 1);
|
||||
} else {
|
||||
c->isfullscreen = 0;
|
||||
c->isfakefullscreen = 0;
|
||||
c->ismaxmizescreen = 0;
|
||||
client_set_fullscreen(c, false);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -4640,6 +4744,49 @@ void overview_restore(Client *c, const Arg *arg) {
|
|||
}
|
||||
}
|
||||
|
||||
void switch_proportion_preset(const Arg *arg) {
|
||||
float target_proportion = 0;
|
||||
|
||||
if(LENGTH(scroller_proportion_preset) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (selmon->sel) {
|
||||
|
||||
for (int i = 0; i < LENGTH(scroller_proportion_preset); i++) {
|
||||
if (scroller_proportion_preset[i] == selmon->sel->scroller_proportion) {
|
||||
if(i == LENGTH(scroller_proportion_preset) -1) {
|
||||
target_proportion = scroller_proportion_preset[0];
|
||||
break;
|
||||
} else {
|
||||
target_proportion = scroller_proportion_preset[i+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (target_proportion == 0) {
|
||||
target_proportion = scroller_proportion_preset[0];
|
||||
}
|
||||
|
||||
unsigned int max_client_width = selmon->w.width - 2 * scroller_structs - gappih;
|
||||
selmon->sel->scroller_proportion = target_proportion;
|
||||
selmon->sel->geom.width = max_client_width * target_proportion;
|
||||
// resize(selmon->sel, selmon->sel->geom, 0);
|
||||
arrange(selmon, false);
|
||||
}
|
||||
}
|
||||
|
||||
void set_proportion(const Arg *arg) {
|
||||
if (selmon->sel) {
|
||||
unsigned int max_client_width = selmon->w.width - 2 * scroller_structs - gappih;
|
||||
selmon->sel->scroller_proportion = arg->f;
|
||||
selmon->sel->geom.width = max_client_width * arg->f;
|
||||
// resize(selmon->sel, selmon->sel->geom, 0);
|
||||
arrange(selmon, false);
|
||||
}
|
||||
}
|
||||
|
||||
// 显示所有tag 或 跳转到聚焦窗口的tag
|
||||
void toggleoverview(const Arg *arg) {
|
||||
|
||||
|
|
@ -4684,7 +4831,7 @@ void toggleoverview(const Arg *arg) {
|
|||
wl_list_for_each(c, &clients, link) {
|
||||
if (c &&
|
||||
(c != selmon->sel || c->overview_isfloatingbak ||
|
||||
c->overview_isfullscreenbak || c->overview_isfakefullscreenbak) &&
|
||||
c->overview_isfullscreenbak || c->overview_ismaxmizescreenbak) &&
|
||||
!c->iskilling && client_surface(c)->mapped)
|
||||
overview_restore(c, &(Arg){.ui = target});
|
||||
}
|
||||
|
|
@ -4705,7 +4852,7 @@ void tile(Monitor *m, unsigned int gappo, unsigned int uappi) {
|
|||
wl_list_for_each(c, &clients,
|
||||
link) if (VISIBLEON(c, m) && !c->animation.tagouting &&
|
||||
!c->iskilling && !c->isfloating &&
|
||||
!c->isfullscreen && !c->isfakefullscreen) n++;
|
||||
!c->isfullscreen && !c->ismaxmizescreen) n++;
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
|
|
@ -4724,7 +4871,7 @@ void tile(Monitor *m, unsigned int gappo, unsigned int uappi) {
|
|||
my = ty = m->gappoh * oe;
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (!VISIBLEON(c, m) || c->iskilling || c->animation.tagouting ||
|
||||
c->isfloating || c->isfullscreen || c->isfakefullscreen)
|
||||
c->isfloating || c->isfullscreen || c->ismaxmizescreen)
|
||||
continue;
|
||||
if (i < selmon->pertag->nmasters[selmon->pertag->curtag]) {
|
||||
r = MIN(n, selmon->pertag->nmasters[selmon->pertag->curtag]) - i;
|
||||
|
|
@ -4757,9 +4904,9 @@ void togglefloating(const Arg *arg) {
|
|||
if (!sel)
|
||||
return;
|
||||
|
||||
if (sel->isfullscreen || sel->isfakefullscreen) {
|
||||
if (sel->isfullscreen || sel->ismaxmizescreen) {
|
||||
sel->isfullscreen = 0; // 清除窗口全屏标志
|
||||
sel->isfakefullscreen = 0;
|
||||
sel->ismaxmizescreen = 0;
|
||||
sel->bw = borderpx; // 恢复非全屏的border
|
||||
}
|
||||
/* return if fullscreen */
|
||||
|
|
@ -4775,7 +4922,7 @@ void togglefullscreen(const Arg *arg) {
|
|||
// if(sel->isfloating)
|
||||
// setfloating(sel, 0);
|
||||
|
||||
if (sel->isfullscreen || sel->isfakefullscreen)
|
||||
if (sel->isfullscreen || sel->ismaxmizescreen)
|
||||
setfullscreen(sel, 0);
|
||||
else
|
||||
setfullscreen(sel, 1);
|
||||
|
|
@ -4784,7 +4931,7 @@ void togglefullscreen(const Arg *arg) {
|
|||
sel->is_in_scratchpad = 0;
|
||||
}
|
||||
|
||||
void togglefakefullscreen(const Arg *arg) {
|
||||
void togglemaxmizescreen(const Arg *arg) {
|
||||
Client *sel = focustop(selmon);
|
||||
if (!sel)
|
||||
return;
|
||||
|
|
@ -4792,10 +4939,10 @@ void togglefakefullscreen(const Arg *arg) {
|
|||
// if(sel->isfloating)
|
||||
// setfloating(sel, 0);
|
||||
|
||||
if (sel->isfullscreen || sel->isfakefullscreen)
|
||||
setfakefullscreen(sel, 0);
|
||||
if (sel->isfullscreen || sel->ismaxmizescreen)
|
||||
setmaxmizescreen(sel, 0);
|
||||
else
|
||||
setfakefullscreen(sel, 1);
|
||||
setmaxmizescreen(sel, 1);
|
||||
|
||||
sel->is_scratchpad_show = 0;
|
||||
sel->is_in_scratchpad = 0;
|
||||
|
|
@ -4864,6 +5011,9 @@ void unmapnotify(struct wl_listener *listener, void *data) {
|
|||
grabc = NULL;
|
||||
}
|
||||
|
||||
if (c == selmon->prevsel)
|
||||
selmon->prevsel = NULL;
|
||||
|
||||
if (c == selmon->sel) {
|
||||
selmon->sel = NULL;
|
||||
Client *nextfocus = focustop(selmon);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue