diff --git a/main.c b/main.c index 97faf9a..3370ac0 100644 --- a/main.c +++ b/main.c @@ -18,24 +18,24 @@ #include #include #include -#include #include -#include #include #include +#include #include +#include #include -#include #include +#include #include // #include +#include #include #include #include #include #include #include -#include #include #include #include @@ -56,16 +56,16 @@ #include #include #include -#include -#include -#include #include #include #include +#include +#include +#include #include #ifdef XWAYLAND -#include #include +#include #include #endif @@ -73,54 +73,74 @@ #include "util.h" #include "wlr_foreign_toplevel_management_v1.h" - /* macros */ -#define MAX(A, B) ((A) > (B) ? (A) : (B)) -#define MIN(A, B) ((A) < (B) ? (A) : (B)) -#define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS) -#define VISIBLEON(C, M) ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags])) -#define LENGTH(X) (sizeof X / sizeof X[0]) -#define END(A) ((A) + LENGTH(A)) -#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) -#define LISTEN_STATIC(E, H) do { static struct wl_listener _l = {.notify = (H)}; wl_signal_add((E), &_l); } while (0) +#define MAX(A, B) ((A) > (B) ? (A) : (B)) +#define MIN(A, B) ((A) < (B) ? (A) : (B)) +#define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS) +#define VISIBLEON(C, M) \ + ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags])) +#define LENGTH(X) (sizeof X / sizeof X[0]) +#define END(A) ((A) + LENGTH(A)) +#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) +#define LISTEN_STATIC(E, H) \ + do { \ + static struct wl_listener _l = {.notify = (H)}; \ + wl_signal_add((E), &_l); \ + } while (0) /* enums */ /* enums */ enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */ -enum { XDGShell, LayerShell, X11 }; /* client types */ -enum { AxisUp, AxisRight, AxisDown, AxisLeft }; //滚轮滚动的方向 -enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrFS, LyrTop, LyrOverlay, +enum { XDGShell, LayerShell, X11 }; /* client types */ +enum { AxisUp, AxisRight, AxisDown, AxisLeft }; // 滚轮滚动的方向 +enum { + LyrBg, + LyrBottom, + LyrTile, + LyrFloat, + LyrFS, + LyrTop, + LyrOverlay, #ifdef IM - LyrIMPopup, + LyrIMPopup, #endif - LyrBlock, NUM_LAYERS }; /* scene layers */ + LyrBlock, + NUM_LAYERS +}; /* scene layers */ #ifdef XWAYLAND -enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar, - NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */ +enum { + NetWMWindowTypeDialog, + NetWMWindowTypeSplash, + NetWMWindowTypeToolbar, + NetWMWindowTypeUtility, + NetLast +}; /* EWMH atoms */ #endif -enum { UP, DOWN, LEFT, RIGHT, UNDIR }; /* movewin */ +enum { UP, DOWN, LEFT, RIGHT, UNDIR }; /* movewin */ typedef union { - int i; - unsigned int ui; - float f; - const void *v; + int i; + unsigned int ui; + float f; + const void *v; } Arg; typedef struct { - unsigned int mod; - unsigned int button; - void (*func)(const Arg *); - const Arg arg; -} Button; //鼠标按键 + unsigned int mod; + unsigned int button; + void (*func)(const Arg *); + const Arg arg; +} Button; // 鼠标按键 typedef struct { - unsigned int mod; - unsigned int dir; - void (*func)(const Arg *); - const Arg arg; + unsigned int mod; + unsigned int dir; + void (*func)(const Arg *); + const Arg arg; } Axis; struct dwl_animation { @@ -138,216 +158,223 @@ struct dwl_animation { struct wlr_box current; }; - typedef struct Pertag Pertag; typedef struct Monitor Monitor; typedef struct { - /* Must keep these three elements in this order */ - unsigned int type; /* XDGShell or X11* */ - struct wlr_box geom,pending,oldgeom,animainit_geom,current; /* layout-relative, includes border */ - Monitor *mon; - struct wlr_scene_tree *scene; - struct wlr_scene_rect *border[4]; /* top, bottom, left, right */ - struct wlr_scene_tree *scene_surface; - struct wl_list link; - struct wl_list flink; - union { - struct wlr_xdg_surface *xdg; - struct wlr_xwayland_surface *xwayland; - } surface; - struct wl_listener commit; - struct wl_listener map; - struct wl_listener maximize; - struct wl_listener minimize; - struct wl_listener unmap; - struct wl_listener destroy; - struct wl_listener set_title; - struct wl_listener fullscreen; - struct wlr_box prev; /* layout-relative, includes border */ + /* Must keep these three elements in this order */ + unsigned int type; /* XDGShell or X11* */ + struct wlr_box geom, pending, oldgeom, animainit_geom, + current; /* layout-relative, includes border */ + Monitor *mon; + struct wlr_scene_tree *scene; + struct wlr_scene_rect *border[4]; /* top, bottom, left, right */ + struct wlr_scene_tree *scene_surface; + struct wl_list link; + struct wl_list flink; + union { + struct wlr_xdg_surface *xdg; + struct wlr_xwayland_surface *xwayland; + } surface; + struct wl_listener commit; + struct wl_listener map; + struct wl_listener maximize; + struct wl_listener minimize; + struct wl_listener unmap; + struct wl_listener destroy; + struct wl_listener set_title; + struct wl_listener fullscreen; + struct wlr_box prev; /* layout-relative, includes border */ #ifdef XWAYLAND - struct wl_listener activate; - struct wl_listener associate; - struct wl_listener dissociate; - struct wl_listener configure; - struct wl_listener set_hints; + struct wl_listener activate; + struct wl_listener associate; + struct wl_listener dissociate; + struct wl_listener configure; + struct wl_listener set_hints; #endif - unsigned int bw; - unsigned int tags,oldtags; - bool dirty; - uint32_t configure_serial; - struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel; - int isfloating, isurgent, isfullscreen, istiled, isminied; - int isfakefullscreen; - 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,overview_isfloatingbak; - uint32_t resize; /* configure serial of a pending resize */ + unsigned int bw; + unsigned int tags, oldtags; + bool dirty; + uint32_t configure_serial; + struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel; + int isfloating, isurgent, isfullscreen, istiled, isminied; + int isfakefullscreen; + 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, + overview_isfloatingbak; + uint32_t resize; /* configure serial of a pending resize */ - struct wlr_xdg_toplevel_decoration_v1 *decoration; - struct wl_listener foreign_activate_request; - struct wl_listener foreign_fullscreen_request; - struct wl_listener foreign_close_request; - struct wl_listener foreign_destroy; - struct wl_listener set_decoration_mode; - struct wl_listener destroy_decoration; + struct wlr_xdg_toplevel_decoration_v1 *decoration; + struct wl_listener foreign_activate_request; + struct wl_listener foreign_fullscreen_request; + struct wl_listener foreign_close_request; + struct wl_listener foreign_destroy; + struct wl_listener set_decoration_mode; + struct wl_listener destroy_decoration; - unsigned int ignore_clear_fullscreen; - const char *animation_type; - int is_in_scratchpad; - int is_scratchpad_show; - int isglobal; - int isnoborder; - int iskilling; - struct wlr_box bounds; - bool resizing; - bool is_open_animation; - bool is_restoring_from_ov; + unsigned int ignore_clear_fullscreen; + const char *animation_type; + int is_in_scratchpad; + int is_scratchpad_show; + int isglobal; + int isnoborder; + int iskilling; + struct wlr_box bounds; + bool resizing; + bool is_open_animation; + bool is_restoring_from_ov; - struct dwl_animation animation; + struct dwl_animation animation; } Client; typedef struct { - struct wl_list link; - struct wl_resource *resource; - Monitor *monitor; + struct wl_list link; + struct wl_resource *resource; + Monitor *monitor; } DwlIpcOutput; typedef struct { - uint32_t mod; - xkb_keysym_t keysym; - void (*func)(const Arg *); - const Arg arg; + uint32_t mod; + xkb_keysym_t keysym; + void (*func)(const Arg *); + const Arg arg; } Key; typedef struct { - struct wl_list link; - struct wlr_keyboard *wlr_keyboard; + struct wl_list link; + struct wlr_keyboard *wlr_keyboard; - int nsyms; - const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */ - uint32_t mods; /* invalid if nsyms == 0 */ - struct wl_event_source *key_repeat_source; + int nsyms; + const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */ + uint32_t mods; /* invalid if nsyms == 0 */ + struct wl_event_source *key_repeat_source; - struct wl_listener modifiers; - struct wl_listener key; - struct wl_listener destroy; + struct wl_listener modifiers; + struct wl_listener key; + struct wl_listener destroy; } Keyboard; typedef struct { - /* Must keep these three elements in this order */ - unsigned int type; /* LayerShell */ - struct wlr_box geom; - Monitor *mon; - struct wlr_scene_tree *scene; - struct wlr_scene_tree *popups; - struct wlr_scene_layer_surface_v1 *scene_layer; - struct wl_list link; - int mapped; - struct wlr_layer_surface_v1 *layer_surface; + /* Must keep these three elements in this order */ + unsigned int type; /* LayerShell */ + struct wlr_box geom; + Monitor *mon; + struct wlr_scene_tree *scene; + struct wlr_scene_tree *popups; + struct wlr_scene_layer_surface_v1 *scene_layer; + struct wl_list link; + int mapped; + struct wlr_layer_surface_v1 *layer_surface; - struct wl_listener destroy; - struct wl_listener map; - struct wl_listener unmap; - struct wl_listener surface_commit; + struct wl_listener destroy; + struct wl_listener map; + struct wl_listener unmap; + struct wl_listener surface_commit; } LayerSurface; typedef struct { - const char *symbol; - void (*arrange)(Monitor *,unsigned int,unsigned int); + const char *symbol; + void (*arrange)(Monitor *, unsigned int, unsigned int); } Layout; struct Monitor { - struct wl_list link; - struct wlr_output *wlr_output; - struct wlr_scene_output *scene_output; - // struct wlr_scene_rect *fullscreen_bg; /* See createmon() for info */ - struct wl_listener frame; - struct wl_listener destroy; - struct wl_listener request_state; - struct wl_listener destroy_lock_surface; - struct wlr_session_lock_surface_v1 *lock_surface; - struct wlr_box m; /* monitor area, layout-relative */ - struct wlr_box w; /* window area, layout-relative */ - struct wl_list layers[4]; /* LayerSurface::link */ - const Layout *lt[2]; - unsigned int seltags; - unsigned int sellt; - uint32_t tagset[2]; - double mfact; - int nmaster; - char ltsymbol[16]; + struct wl_list link; + struct wlr_output *wlr_output; + struct wlr_scene_output *scene_output; + // struct wlr_scene_rect *fullscreen_bg; /* See createmon() for info */ + struct wl_listener frame; + struct wl_listener destroy; + struct wl_listener request_state; + struct wl_listener destroy_lock_surface; + struct wlr_session_lock_surface_v1 *lock_surface; + struct wlr_box m; /* monitor area, layout-relative */ + struct wlr_box w; /* window area, layout-relative */ + struct wl_list layers[4]; /* LayerSurface::link */ + const Layout *lt[2]; + unsigned int seltags; + unsigned int sellt; + uint32_t tagset[2]; + double mfact; + int nmaster; + char ltsymbol[16]; - struct wl_list dwl_ipc_outputs; - int gappih; /* horizontal gap between windows */ - int gappiv; /* vertical gap between windows */ - int gappoh; /* horizontal outer gaps */ - int gappov; /* vertical outer gaps */ - Pertag *pertag; - Client *sel; - int isoverview; - int is_in_hotarea; - int gamma_lut_changed; + struct wl_list dwl_ipc_outputs; + int gappih; /* horizontal gap between windows */ + int gappiv; /* vertical gap between windows */ + int gappoh; /* horizontal outer gaps */ + int gappov; /* vertical outer gaps */ + Pertag *pertag; + Client *sel; + int isoverview; + int is_in_hotarea; + int gamma_lut_changed; }; typedef struct { - const char *name; - float mfact; - int nmaster; - float scale; - const Layout *lt; - enum wl_output_transform rr; - int x, y; + const char *name; + float mfact; + int nmaster; + float scale; + const Layout *lt; + enum wl_output_transform rr; + int x, y; } MonitorRule; typedef struct { - struct wlr_pointer_constraint_v1 *constraint; - struct wl_listener destroy; + struct wlr_pointer_constraint_v1 *constraint; + struct wl_listener destroy; } PointerConstraint; typedef struct { - const char *id; - const char *title; - unsigned int tags; - int isfloating; - int isfullscreen; - const char *animation_type; - int isnoborder; - int monitor; - unsigned int width; - unsigned int height; + const char *id; + const char *title; + unsigned int tags; + int isfloating; + int isfullscreen; + const char *animation_type; + int isnoborder; + int monitor; + unsigned int width; + unsigned int height; } Rule; typedef struct { - struct wlr_scene_tree *scene; + struct wlr_scene_tree *scene; - struct wlr_session_lock_v1 *lock; - struct wl_listener new_surface; - struct wl_listener unlock; - struct wl_listener destroy; + struct wlr_session_lock_v1 *lock; + struct wl_listener new_surface; + struct wl_listener unlock; + struct wl_listener destroy; } SessionLock; /* function declarations */ -static void logtofile(const char *fmt, ...); //日志函数 -static void lognumtofile(unsigned int num); //日志函数 -static void applybounds(Client *c, struct wlr_box *bbox); //设置边界规则,能让一些窗口拥有比较适合的大小 -static void applyrules(Client *c); //窗口规则应用,应用config.h中定义的窗口规则 -static void arrange(Monitor *m,bool want_animation); //布局函数,让窗口俺平铺规则移动和重置大小 -static void arrangelayer(Monitor *m, struct wl_list *list, -struct wlr_box *usable_area, int exclusive); +static void logtofile(const char *fmt, ...); // 日志函数 +static void lognumtofile(unsigned int num); // 日志函数 +static void applybounds( + Client *c, + struct wlr_box *bbox); // 设置边界规则,能让一些窗口拥有比较适合的大小 +static void applyrules(Client *c); // 窗口规则应用,应用config.h中定义的窗口规则 +static void +arrange(Monitor *m, + bool want_animation); // 布局函数,让窗口俺平铺规则移动和重置大小 +static void arrangelayer(Monitor *m, struct wl_list *list, + struct wlr_box *usable_area, int exclusive); static void arrangelayers(Monitor *m); -static void autostartexec(void); //自启动命令执行 -static void axisnotify(struct wl_listener *listener, void *data); //滚轮事件处理 -static void buttonpress(struct wl_listener *listener, void *data); //鼠标按键事件处理 -static void chvt(const Arg *arg); +static void autostartexec(void); // 自启动命令执行 +static void axisnotify(struct wl_listener *listener, void *data); // 滚轮事件处理 +static void buttonpress(struct wl_listener *listener, + void *data); // 鼠标按键事件处理 +static void chvt(const Arg *arg); static void checkidleinhibitor(struct wlr_surface *exclude); -static void cleanup(void); //退出清理 -static void cleanupkeyboard(struct wl_listener *listener, void *data); //退出清理 -static void cleanupmon(struct wl_listener *listener, void *data); //退出清理 -static void closemon(Monitor *m); //退出清理 -static void toggle_hotarea(int x_root, int y_root); //触发热区 +static void cleanup(void); // 退出清理 +static void cleanupkeyboard(struct wl_listener *listener, + void *data); // 退出清理 +static void cleanupmon(struct wl_listener *listener, void *data); // 退出清理 +static void closemon(Monitor *m); // 退出清理 +static void toggle_hotarea(int x_root, int y_root); // 触发热区 static void commitlayersurfacenotify(struct wl_listener *listener, void *data); static void commitnotify(struct wl_listener *listener, void *data); static void createdecoration(struct wl_listener *listener, void *data); @@ -376,17 +403,29 @@ static void destroysessionlock(struct wl_listener *listener, void *data); static void destroysessionmgr(struct wl_listener *listener, void *data); static Monitor *dirtomon(enum wlr_direction dir); static void setcursorshape(struct wl_listener *listener, void *data); -static void dwl_ipc_manager_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id); +static void dwl_ipc_manager_bind(struct wl_client *client, void *data, + uint32_t version, uint32_t id); static void dwl_ipc_manager_destroy(struct wl_resource *resource); -static void dwl_ipc_manager_get_output(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *output); -static void dwl_ipc_manager_release(struct wl_client *client, struct wl_resource *resource); +static void dwl_ipc_manager_get_output(struct wl_client *client, + struct wl_resource *resource, + uint32_t id, struct wl_resource *output); +static void dwl_ipc_manager_release(struct wl_client *client, + struct wl_resource *resource); static void dwl_ipc_output_destroy(struct wl_resource *resource); static void dwl_ipc_output_printstatus(Monitor *monitor); static void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output); -static void dwl_ipc_output_set_client_tags(struct wl_client *client, struct wl_resource *resource, uint32_t and_tags, uint32_t xor_tags); -static void dwl_ipc_output_set_layout(struct wl_client *client, struct wl_resource *resource, uint32_t index); -static void dwl_ipc_output_set_tags(struct wl_client *client, struct wl_resource *resource, uint32_t tagmask, uint32_t toggle_tagset); -static void dwl_ipc_output_release(struct wl_client *client, struct wl_resource *resource); +static void dwl_ipc_output_set_client_tags(struct wl_client *client, + struct wl_resource *resource, + uint32_t and_tags, + uint32_t xor_tags); +static void dwl_ipc_output_set_layout(struct wl_client *client, + struct wl_resource *resource, + uint32_t index); +static void dwl_ipc_output_set_tags(struct wl_client *client, + struct wl_resource *resource, + uint32_t tagmask, uint32_t toggle_tagset); +static void dwl_ipc_output_release(struct wl_client *client, + struct wl_resource *resource); static void focusclient(Client *c, int lift); static void focusmon(const Arg *arg); static void focusstack(const Arg *arg); @@ -415,18 +454,20 @@ static void maximizenotify(struct wl_listener *listener, void *data); static void minimizenotify(struct wl_listener *listener, void *data); static void monocle(Monitor *m); static void motionabsolute(struct wl_listener *listener, void *data); -static void motionnotify(uint32_t time, struct wlr_input_device *device, double sx, - double sy, double sx_unaccel, double sy_unaccel); +static void motionnotify(uint32_t time, struct wlr_input_device *device, + double sx, double sy, double sx_unaccel, + double sy_unaccel); static void motionrelative(struct wl_listener *listener, void *data); static void moveresize(const Arg *arg); static void exchange_client(const Arg *arg); static void reset_foreign_tolevel(Client *c); static void exchange_two_client(Client *c1, Client *c2); static void outputmgrapply(struct wl_listener *listener, void *data); -static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test); +static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, + int test); static void outputmgrtest(struct wl_listener *listener, void *data); -static void pointerfocus(Client *c, struct wlr_surface *surface, - double sx, double sy, uint32_t time); +static void pointerfocus(Client *c, struct wlr_surface *surface, double sx, + double sy, uint32_t time); static void printstatus(void); static void quit(const Arg *arg); static void quitsignal(int signo); @@ -434,7 +475,7 @@ static void rendermon(struct wl_listener *listener, void *data); static void requestdecorationmode(struct wl_listener *listener, void *data); static void requeststartdrag(struct wl_listener *listener, void *data); static void resize(Client *c, struct wlr_box geo, int interact); -static void resizeclient(Client *c,int x,int y,int w,int h, int interact); +static void resizeclient(Client *c, int x, int y, int w, int h, int interact); static void run(char *startup_cmd); static void setcursor(struct wl_listener *listener, void *data); static void setfloating(Client *c, int floating); @@ -469,7 +510,7 @@ static void unmapnotify(struct wl_listener *listener, void *data); static void updatemons(struct wl_listener *listener, void *data); static void updatetitle(struct wl_listener *listener, void *data); static void urgent(struct wl_listener *listener, void *data); -static void view(const Arg *arg,bool want_animation); +static void view(const Arg *arg, bool want_animation); static void bind_to_view(const Arg *arg); static void viewtoleft_have_client(const Arg *arg); static void viewtoright_have_client(const Arg *arg); @@ -477,13 +518,13 @@ static void viewtoleft(const Arg *arg); static void viewtoright(const Arg *arg); static void handlesig(int signo); static void tagtoleft(const Arg *arg); -static void tagtoright(const Arg *arg); +static void tagtoright(const Arg *arg); static void virtualkeyboard(struct wl_listener *listener, void *data); static void virtualpointer(struct wl_listener *listener, void *data); static void warp_cursor(const Client *c); static Monitor *xytomon(double x, double y); static void xytonode(double x, double y, struct wlr_surface **psurface, - Client **pc, LayerSurface **pl, double *nx, double *ny); + Client **pc, LayerSurface **pl, double *nx, double *ny); static void zoom(const Arg *arg); static void clear_fullscreen_flag(Client *c); static Client *direction_select(const Arg *arg); @@ -502,16 +543,19 @@ static void show_scratchpad(Client *c); static void show_hide_client(Client *c); static void tag_client(const Arg *arg, Client *target_client); -static void handle_foreign_activate_request(struct wl_listener *listener, void *data); -static void handle_foreign_fullscreen_request(struct wl_listener *listener, void *data); -static void handle_foreign_close_request(struct wl_listener *listener, void *data); +static void handle_foreign_activate_request(struct wl_listener *listener, + void *data); +static void handle_foreign_fullscreen_request(struct wl_listener *listener, + void *data); +static void handle_foreign_close_request(struct wl_listener *listener, + void *data); static void handle_foreign_destroy(struct wl_listener *listener, void *data); static struct wlr_box setclient_coordinate_center(struct wlr_box geom); static unsigned int get_tags_first_tag(unsigned int tags); void client_commit(Client *c); -void apply_border(Client *c,struct wlr_box clip_box); +void apply_border(Client *c, struct wlr_box clip_box); void client_set_opacity(Client *c, double opacity); /* variables */ @@ -552,9 +596,10 @@ static struct wlr_session *session; static struct wlr_session_lock_manager_v1 *session_lock_mgr; static struct wlr_scene_rect *locked_bg; static struct wlr_session_lock_v1 *cur_lock; -static const int layermap[] = { LyrBg, LyrBottom, LyrTop, LyrOverlay }; +static const int layermap[] = {LyrBg, LyrBottom, LyrTop, LyrOverlay}; static struct wlr_scene_tree *drag_icon; -static struct wlr_cursor_shape_manager_v1 *cursor_shape_mgr; //这个跟steup obs影响对应 +static struct wlr_cursor_shape_manager_v1 + *cursor_shape_mgr; // 这个跟steup obs影响对应 static struct wlr_pointer_constraints_v1 *pointer_constraints; static struct wlr_relative_pointer_manager_v1 *relative_pointer_mgr; static struct wlr_pointer_constraint_v1 *active_constraint; @@ -570,12 +615,18 @@ static struct wlr_box sgeom; static struct wl_list mons; static Monitor *selmon; -static int enablegaps = 1; /* enables gaps, used by togglegaps */ +static int enablegaps = 1; /* enables gaps, used by togglegaps */ static int axis_apply_time = 0; /* global event handlers */ -static struct zdwl_ipc_manager_v2_interface dwl_manager_implementation = {.release = dwl_ipc_manager_release, .get_output = dwl_ipc_manager_get_output}; -static struct zdwl_ipc_output_v2_interface dwl_output_implementation = {.release = dwl_ipc_output_release, .set_tags = dwl_ipc_output_set_tags, .set_layout = dwl_ipc_output_set_layout, .set_client_tags = dwl_ipc_output_set_client_tags}; +static struct zdwl_ipc_manager_v2_interface dwl_manager_implementation = { + .release = dwl_ipc_manager_release, + .get_output = dwl_ipc_manager_get_output}; +static struct zdwl_ipc_output_v2_interface dwl_output_implementation = { + .release = dwl_ipc_output_release, + .set_tags = dwl_ipc_output_set_tags, + .set_layout = dwl_ipc_output_set_layout, + .set_client_tags = dwl_ipc_output_set_client_tags}; static struct wl_listener lock_listener = {.notify = locksession}; #ifdef XWAYLAND @@ -603,14 +654,17 @@ static Atom netatom[NetLast]; #endif /* compile-time check if all tags fit into an unsigned int bit array. */ -struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; +struct NumTags { + char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; +}; struct Pertag { - unsigned int curtag, prevtag; /* current and previous tag */ - int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ - float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ - unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */ - const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */ + unsigned int curtag, prevtag; /* current and previous tag */ + int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ + float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ + unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */ + const Layout + *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */ }; static pid_t *autostart_pids; @@ -623,17 +677,14 @@ struct vec2 { #define BAKED_POINTS_COUNT 256 struct vec2 *baked_points; -struct vec2 -calculate_animation_curve_at(double t) { +struct vec2 calculate_animation_curve_at(double t) { struct vec2 point; - point.x = 3 * t * (1 - t) * (1 - t) * animation_curve[0] - + 3 * t * t * (1 - t) * animation_curve[2] - + t * t * t; + point.x = 3 * t * (1 - t) * (1 - t) * animation_curve[0] + + 3 * t * t * (1 - t) * animation_curve[2] + t * t * t; - point.y = 3 * t * (1 - t) * (1 - t) * animation_curve[1] - + 3 * t * t * (1 - t) * animation_curve[3] - + t * t * t; + point.y = 3 * t * (1 - t) * (1 - t) * animation_curve[1] + + 3 * t * t * (1 - t) * animation_curve[3] + t * t * t; return point; } @@ -641,20 +692,20 @@ calculate_animation_curve_at(double t) { void init_baked_points() { baked_points = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points)); - for(size_t i = 0; i < BAKED_POINTS_COUNT; i++) { - baked_points[i] = calculate_animation_curve_at((double)i / (BAKED_POINTS_COUNT - 1)); - } + for (size_t i = 0; i < BAKED_POINTS_COUNT; i++) { + baked_points[i] = + calculate_animation_curve_at((double)i / (BAKED_POINTS_COUNT - 1)); + } } -double -find_animation_curve_at(double t) { +double find_animation_curve_at(double t) { size_t down = 0; size_t up = BAKED_POINTS_COUNT - 1; size_t middle = (up + down) / 2; - while(up - down != 1) { - if(baked_points[middle].x <= t) { - down = middle; + while (up - down != 1) { + if (baked_points[middle].x <= t) { + down = middle; } else { up = middle; } @@ -664,303 +715,293 @@ find_animation_curve_at(double t) { return baked_points[up].y; } -bool -client_animation_next_tick(Client *c) -{ - double animation_passed = - (double)c->animation.passed_frames / c->animation.total_frames; - double factor = find_animation_curve_at(animation_passed); +bool client_animation_next_tick(Client *c) { + double animation_passed = + (double)c->animation.passed_frames / c->animation.total_frames; + double factor = find_animation_curve_at(animation_passed); - uint32_t width = c->animation.initial.width + - (c->current.width - c->animation.initial.width) * factor; - uint32_t height = c->animation.initial.height + - (c->current.height - c->animation.initial.height) * factor; + uint32_t width = c->animation.initial.width + + (c->current.width - c->animation.initial.width) * factor; + uint32_t height = c->animation.initial.height + + (c->current.height - c->animation.initial.height) * factor; - uint32_t x = c->animation.initial.x + - (c->current.x - c->animation.initial.x) * factor; - uint32_t y = c->animation.initial.y + - (c->current.y - c->animation.initial.y) * factor; + uint32_t x = + c->animation.initial.x + (c->current.x - c->animation.initial.x) * factor; + uint32_t y = + c->animation.initial.y + (c->current.y - c->animation.initial.y) * factor; - wlr_scene_node_set_position(&c->scene->node, x, y); - c->animation.current = (struct wlr_box){ - .x = x, - .y = y, - .width = width, - .height = height, - }; + wlr_scene_node_set_position(&c->scene->node, x, y); + c->animation.current = (struct wlr_box){ + .x = x, + .y = y, + .width = width, + .height = height, + }; - if(!c->iskilling && (c->is_open_animation||c->animation.begin_fade_in) && animation_fade_in) { - c->animation.begin_fade_in = true; - client_set_opacity(c,MIN(animation_passed + fadein_begin_opacity,1.0)); - } + if (!c->iskilling && (c->is_open_animation || c->animation.begin_fade_in) && + animation_fade_in) { + c->animation.begin_fade_in = true; + client_set_opacity(c, MIN(animation_passed + fadein_begin_opacity, 1.0)); + } - if(c->iskilling) { - client_set_opacity(c,MAX(fadeout_begin_opacity - animation_passed ,0.1) ); - } + if (c->iskilling) { + client_set_opacity(c, MAX(fadeout_begin_opacity - animation_passed, 0.1)); + } - c->is_open_animation = false; + c->is_open_animation = false; - if (animation_passed == 1.0) - { - if(c->animation.begin_fade_in) { - c->animation.begin_fade_in = false; - } + if (animation_passed == 1.0) { + if (c->animation.begin_fade_in) { + c->animation.begin_fade_in = false; + } - c->animation.running = false; - if(c->iskilling) { - client_send_close(c); - return false; - } - if(c->animation.tagouting) { - c->animation.tagouting = false; - wlr_scene_node_set_enabled(&c->scene->node, false); - client_set_suspended(c, true); - c->animation.tagouted = true; - } - return false; - } - else - { - c->animation.passed_frames++; - return true; - } + c->animation.running = false; + if (c->iskilling) { + client_send_close(c); + return false; + } + if (c->animation.tagouting) { + c->animation.tagouting = false; + wlr_scene_node_set_enabled(&c->scene->node, false); + client_set_suspended(c, true); + c->animation.tagouted = true; + } + return false; + } else { + c->animation.passed_frames++; + return true; + } } -void -client_actual_size(Client *c, uint32_t *width, uint32_t *height) -{ - *width = c->animation.running - ? MIN(c->animation.current.width, c->current.width) - : c->current.width; +void client_actual_size(Client *c, uint32_t *width, uint32_t *height) { + *width = c->animation.running + ? MIN(c->animation.current.width, c->current.width) + : c->current.width; - *height = c->animation.running - ? MIN(c->animation.current.height, c->current.height) - : c->current.height; + *height = c->animation.running + ? MIN(c->animation.current.height, c->current.height) + : c->current.height; } -void -apply_border(Client *c,struct wlr_box clip_box) { - wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); - wlr_scene_rect_set_size(c->border[0], clip_box.width, c->bw); - wlr_scene_rect_set_size(c->border[1], clip_box.width, c->bw); - wlr_scene_rect_set_size(c->border[2], c->bw, clip_box.height - 2 * c->bw); - wlr_scene_rect_set_size(c->border[3], c->bw, clip_box.height - 2 * c->bw); - wlr_scene_node_set_position(&c->border[1]->node, 0, clip_box.height - c->bw); - wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw); - wlr_scene_node_set_position(&c->border[3]->node, clip_box.width - c->bw, c->bw); - wlr_scene_node_set_position(&c->border[1]->node, 0, clip_box.height - c->bw); - wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw); - wlr_scene_node_set_position(&c->border[3]->node, clip_box.width - c->bw, c->bw); +void apply_border(Client *c, struct wlr_box clip_box) { + wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); + wlr_scene_rect_set_size(c->border[0], clip_box.width, c->bw); + wlr_scene_rect_set_size(c->border[1], clip_box.width, c->bw); + wlr_scene_rect_set_size(c->border[2], c->bw, clip_box.height - 2 * c->bw); + wlr_scene_rect_set_size(c->border[3], c->bw, clip_box.height - 2 * c->bw); + wlr_scene_node_set_position(&c->border[1]->node, 0, clip_box.height - c->bw); + wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw); + wlr_scene_node_set_position(&c->border[3]->node, clip_box.width - c->bw, + c->bw); + wlr_scene_node_set_position(&c->border[1]->node, 0, clip_box.height - c->bw); + wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw); + wlr_scene_node_set_position(&c->border[3]->node, clip_box.width - c->bw, + c->bw); } -void -client_apply_clip(Client *c) -{ - uint32_t width, height; - client_actual_size(c, &width, &height); +void client_apply_clip(Client *c) { + uint32_t width, height; + client_actual_size(c, &width, &height); - struct wlr_box geometry; - client_get_geometry(c,&geometry); - struct wlr_box clip_box = (struct wlr_box){ - .x = geometry.x, - .y = geometry.y, - .width = width, - .height = height, - }; + struct wlr_box geometry; + client_get_geometry(c, &geometry); + struct wlr_box clip_box = (struct wlr_box){ + .x = geometry.x, + .y = geometry.y, + .width = width, + .height = height, + }; - if (client_is_x11(c)) - { - clip_box.x = 0; - clip_box.y = 0; - } + if (client_is_x11(c)) { + clip_box.x = 0; + clip_box.y = 0; + } - wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box); - apply_border(c, clip_box); + wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box); + apply_border(c, clip_box); } -bool client_draw_frame(Client *c) -{ - if (!c || !c->mon || !client_surface(c)->mapped) - return false; - // if (!VISIBLEON(c, c->mon)) - // return false; - bool need_more_frames = false; - if (c->animation.running) { - if (client_animation_next_tick(c)) - { - need_more_frames = true; - } - } else { - wlr_scene_node_set_position(&c->scene->node, c->pending.x, c->pending.y); - apply_border(c, c->pending); - } - - client_apply_clip(c); +bool client_draw_frame(Client *c) { + if (!c || !c->mon || !client_surface(c)->mapped) + return false; + // if (!VISIBLEON(c, c->mon)) + // return false; + bool need_more_frames = false; + if (c->animation.running) { + if (client_animation_next_tick(c)) { + need_more_frames = true; + } + } else { + wlr_scene_node_set_position(&c->scene->node, c->pending.x, c->pending.y); + apply_border(c, c->pending); + } - return need_more_frames; + client_apply_clip(c); + + return need_more_frames; } -void //0.5 -applybounds(Client *c, struct wlr_box *bbox) -{ - /* set minimum possible */ - c->geom.width = MAX(1 + 2 * (int)c->bw, c->geom.width); - c->geom.height = MAX(1 + 2 * (int)c->bw, c->geom.height); +void // 0.5 +applybounds(Client *c, struct wlr_box *bbox) { + /* set minimum possible */ + c->geom.width = MAX(1 + 2 * (int)c->bw, c->geom.width); + c->geom.height = MAX(1 + 2 * (int)c->bw, c->geom.height); - if (c->geom.x >= bbox->x + bbox->width) - c->geom.x = bbox->x + bbox->width - c->geom.width; - if (c->geom.y >= bbox->y + bbox->height) - c->geom.y = bbox->y + bbox->height - c->geom.height; - if (c->geom.x + c->geom.width <= bbox->x) - c->geom.x = bbox->x; - if (c->geom.y + c->geom.height <= bbox->y) - c->geom.y = bbox->y; + if (c->geom.x >= bbox->x + bbox->width) + c->geom.x = bbox->x + bbox->width - c->geom.width; + if (c->geom.y >= bbox->y + bbox->height) + c->geom.y = bbox->y + bbox->height - c->geom.height; + if (c->geom.x + c->geom.width <= bbox->x) + c->geom.x = bbox->x; + if (c->geom.y + c->geom.height <= bbox->y) + c->geom.y = bbox->y; } /*清除全屏标志,还原全屏时清0的border*/ void clear_fullscreen_flag(Client *c) { if (c->isfullscreen || c->isfakefullscreen) { c->isfullscreen = 0; - c->isfloating = 0; + c->isfloating = 0; c->isfakefullscreen = 0; c->bw = borderpx; - client_set_fullscreen(c, false); + client_set_fullscreen(c, false); } } -void //升级忽略 -setgamma(struct wl_listener *listener, void *data) -{ - struct wlr_gamma_control_manager_v1_set_gamma_event *event = data; - struct wlr_output_state state; - wlr_output_state_init(&state); - if (!wlr_gamma_control_v1_apply(event->control, &state)) { - wlr_output_state_finish(&state); - return; - } +void // 升级忽略 +setgamma(struct wl_listener *listener, void *data) { + struct wlr_gamma_control_manager_v1_set_gamma_event *event = data; + struct wlr_output_state state; + wlr_output_state_init(&state); + if (!wlr_gamma_control_v1_apply(event->control, &state)) { + wlr_output_state_finish(&state); + return; + } - if (!wlr_output_test_state(event->output, &state)) { - wlr_gamma_control_v1_send_failed_and_destroy(event->control); - wlr_output_state_finish(&state); - return; - } + if (!wlr_output_test_state(event->output, &state)) { + wlr_gamma_control_v1_send_failed_and_destroy(event->control); + wlr_output_state_finish(&state); + return; + } - wlr_output_commit_state(event->output, &state); - wlr_output_schedule_frame(event->output); + wlr_output_commit_state(event->output, &state); + wlr_output_schedule_frame(event->output); } void minized(const Arg *arg) { - if(selmon->sel && !selmon->sel->isminied) { - set_minized(selmon->sel); - } + if (selmon->sel && !selmon->sel->isminied) { + set_minized(selmon->sel); + } } void restore_minized(const Arg *arg) { - Client *c; - wl_list_for_each(c, &clients, link) { - if (c->isminied) { - show_hide_client(c); - c->is_scratchpad_show = 0; - c->is_in_scratchpad = 0; - setborder_color(c); - break; - } - } - + Client *c; + wl_list_for_each(c, &clients, link) { + if (c->isminied) { + show_hide_client(c); + c->is_scratchpad_show = 0; + c->is_in_scratchpad = 0; + setborder_color(c); + break; + } + } } void show_scratchpad(Client *c) { - c->is_scratchpad_show = 1; - if (c->isfullscreen || c->isfakefullscreen) { - c->isfullscreen = 0; // 清除窗口全屏标志 - c->isfakefullscreen = 0; - c->bw = borderpx; // 恢复非全屏的border - } - /* return if fullscreen */ - if(!c->isfloating) { - setfloating(c, 1); - c->geom.width = c->mon->w.width * 0.7; - c->geom.height = c->mon->w.height * 0.8; - //重新计算居中的坐标 - c->geom = setclient_coordinate_center(c->geom); - resize(c, c->geom, 0); - } - c->oldtags = selmon->tagset[selmon->seltags]; - show_hide_client(c); - setborder_color(c); + c->is_scratchpad_show = 1; + if (c->isfullscreen || c->isfakefullscreen) { + c->isfullscreen = 0; // 清除窗口全屏标志 + c->isfakefullscreen = 0; + c->bw = borderpx; // 恢复非全屏的border + } + /* return if fullscreen */ + if (!c->isfloating) { + setfloating(c, 1); + c->geom.width = c->mon->w.width * 0.7; + c->geom.height = c->mon->w.height * 0.8; + // 重新计算居中的坐标 + c->geom = setclient_coordinate_center(c->geom); + resize(c, c->geom, 0); + } + c->oldtags = selmon->tagset[selmon->seltags]; + show_hide_client(c); + setborder_color(c); } void reset_foreign_tolevel(Client *c) { - wlr_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel); - c->foreign_toplevel = NULL; - // printstatus(); - //创建外部顶层窗口的句柄,每一个顶层窗口都有一个 - c->foreign_toplevel = wlr_foreign_toplevel_handle_v1_create(foreign_toplevel_manager); - //监听来自外部对于窗口的事件请求 - if(c->foreign_toplevel){ - LISTEN(&(c->foreign_toplevel->events.request_activate), - &c->foreign_activate_request,handle_foreign_activate_request); - LISTEN(&(c->foreign_toplevel->events.request_fullscreen), - &c->foreign_fullscreen_request,handle_foreign_fullscreen_request); - LISTEN(&(c->foreign_toplevel->events.request_close), - &c->foreign_close_request,handle_foreign_close_request); - LISTEN(&(c->foreign_toplevel->events.destroy), - &c->foreign_destroy,handle_foreign_destroy); - //设置外部顶层句柄的id为应用的id - const char *appid; - appid = client_get_appid(c) ; - if(appid) - wlr_foreign_toplevel_handle_v1_set_app_id(c->foreign_toplevel,appid); - //设置外部顶层句柄的title为应用的title - const char *title; - title = client_get_title(c) ; - if(title) - wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel,title); - //设置外部顶层句柄的显示监视器为当前监视器 - wlr_foreign_toplevel_handle_v1_output_enter( - c->foreign_toplevel, c->mon->wlr_output); - } + wlr_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel); + c->foreign_toplevel = NULL; + // printstatus(); + // 创建外部顶层窗口的句柄,每一个顶层窗口都有一个 + c->foreign_toplevel = + wlr_foreign_toplevel_handle_v1_create(foreign_toplevel_manager); + // 监听来自外部对于窗口的事件请求 + if (c->foreign_toplevel) { + LISTEN(&(c->foreign_toplevel->events.request_activate), + &c->foreign_activate_request, handle_foreign_activate_request); + LISTEN(&(c->foreign_toplevel->events.request_fullscreen), + &c->foreign_fullscreen_request, handle_foreign_fullscreen_request); + LISTEN(&(c->foreign_toplevel->events.request_close), + &c->foreign_close_request, handle_foreign_close_request); + LISTEN(&(c->foreign_toplevel->events.destroy), &c->foreign_destroy, + handle_foreign_destroy); + // 设置外部顶层句柄的id为应用的id + const char *appid; + appid = client_get_appid(c); + if (appid) + wlr_foreign_toplevel_handle_v1_set_app_id(c->foreign_toplevel, appid); + // 设置外部顶层句柄的title为应用的title + const char *title; + title = client_get_title(c); + if (title) + wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel, title); + // 设置外部顶层句柄的显示监视器为当前监视器 + wlr_foreign_toplevel_handle_v1_output_enter(c->foreign_toplevel, + c->mon->wlr_output); + } } void toggle_scratchpad(const Arg *arg) { - Client *c; - wl_list_for_each(c, &clients, link) { - if(c->mon != selmon) { - continue; - } - if(c->is_in_scratchpad && c->is_scratchpad_show && (selmon->tagset[selmon->seltags] & c->tags) == 0 ) { - unsigned int target = get_tags_first_tag(selmon->tagset[selmon->seltags]); - tag_client(&(Arg){.ui = target},c); - return; - } else if (c->is_in_scratchpad && c->is_scratchpad_show && (selmon->tagset[selmon->seltags] & c->tags) != 0) { - set_minized(c); - return; - } else if ( c && c->is_in_scratchpad && !c->is_scratchpad_show) { - show_scratchpad(c); - return; - } - } + Client *c; + wl_list_for_each(c, &clients, link) { + if (c->mon != selmon) { + continue; + } + if (c->is_in_scratchpad && c->is_scratchpad_show && + (selmon->tagset[selmon->seltags] & c->tags) == 0) { + unsigned int target = get_tags_first_tag(selmon->tagset[selmon->seltags]); + tag_client(&(Arg){.ui = target}, c); + return; + } else if (c->is_in_scratchpad && c->is_scratchpad_show && + (selmon->tagset[selmon->seltags] & c->tags) != 0) { + set_minized(c); + return; + } else if (c && c->is_in_scratchpad && !c->is_scratchpad_show) { + show_scratchpad(c); + return; + } + } } -void //0.5 -handlesig(int signo) -{ - if (signo == SIGCHLD) { +void // 0.5 +handlesig(int signo) { + if (signo == SIGCHLD) { #ifdef XWAYLAND - siginfo_t in; - /* wlroots expects to reap the XWayland process itself, so we - * use WNOWAIT to keep the child waitable until we know it's not - * XWayland. - */ - while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid - && (!xwayland || in.si_pid != xwayland->server->pid)) - waitpid(in.si_pid, NULL, 0); + siginfo_t in; + /* wlroots expects to reap the XWayland process itself, so we + * use WNOWAIT to keep the child waitable until we know it's not + * XWayland. + */ + while (!waitid(P_ALL, 0, &in, WEXITED | WNOHANG | WNOWAIT) && in.si_pid && + (!xwayland || in.si_pid != xwayland->server->pid)) + waitpid(in.si_pid, NULL, 0); #else - while (waitpid(-1, NULL, WNOHANG) > 0); + while (waitpid(-1, NULL, WNOHANG) > 0) + ; #endif - } else if (signo == SIGINT || signo == SIGTERM) { - quit(NULL); - } + } else if (signo == SIGINT || signo == SIGTERM) { + quit(NULL); + } } void toggle_hotarea(int x_root, int y_root) { @@ -981,15 +1022,14 @@ void toggle_hotarea(int x_root, int y_root) { } } -struct wlr_box //计算客户端居中坐标 -setclient_coordinate_center(struct wlr_box geom){ - struct wlr_box tempbox; - tempbox.x = selmon->w.x + (selmon->w.width - geom.width) / 2; - tempbox.y = selmon->w.y + (selmon->w.height - geom.height) / 2; - tempbox.width = geom.width; - tempbox.height = geom.height; - return tempbox; - +struct wlr_box // 计算客户端居中坐标 +setclient_coordinate_center(struct wlr_box geom) { + struct wlr_box tempbox; + tempbox.x = selmon->w.x + (selmon->w.width - geom.width) / 2; + tempbox.y = selmon->w.y + (selmon->w.height - geom.height) / 2; + tempbox.width = geom.width; + tempbox.height = geom.height; + return tempbox; } /* function implementations */ @@ -1014,2650 +1054,2559 @@ void lognumtofile(unsigned int num) { } int // 0.5 -applyrulesgeom(Client *c) -{ - /* rule matching */ - const char *appid, *title; - const Rule *r; - int hit = 0; +applyrulesgeom(Client *c) { + /* rule matching */ + const char *appid, *title; + const Rule *r; + int hit = 0; - if (!(appid = client_get_appid(c))) - appid = broken; - if (!(title = client_get_title(c))) - title = broken; + if (!(appid = client_get_appid(c))) + appid = broken; + if (!(title = client_get_title(c))) + title = broken; - for (r = rules; r < END(rules); r++) { - if ((!r->title || strstr(title, r->title)) - && (!r->id || strstr(appid, r->id)) && r->width !=0 && r->height != 0) { - c->geom.width = r->width; - c->geom.height = r->height; - //重新计算居中的坐标 - c->geom = setclient_coordinate_center(c->geom); - hit = 1; - break; - } - } - return hit; + for (r = rules; r < END(rules); r++) { + if ((!r->title || strstr(title, r->title)) && + (!r->id || strstr(appid, r->id)) && r->width != 0 && r->height != 0) { + c->geom.width = r->width; + c->geom.height = r->height; + // 重新计算居中的坐标 + c->geom = setclient_coordinate_center(c->geom); + hit = 1; + break; + } + } + return hit; } void // 17 -applyrules(Client *c) -{ - /* rule matching */ - const char *appid, *title; - uint32_t i, newtags = 0; - const Rule *r; - Monitor *mon = selmon, *m; +applyrules(Client *c) { + /* rule matching */ + const char *appid, *title; + uint32_t i, newtags = 0; + const Rule *r; + Monitor *mon = selmon, *m; - c->isfloating = client_is_float_type(c); - if (!(appid = client_get_appid(c))) - appid = broken; - if (!(title = client_get_title(c))) - title = broken; + c->isfloating = client_is_float_type(c); + if (!(appid = client_get_appid(c))) + appid = broken; + if (!(title = client_get_title(c))) + title = broken; - for (r = rules; r < END(rules); r++) { - if ((!r->title || strstr(title, r->title)) - && (!r->id || strstr(appid, r->id))) { - c->isfloating = r->isfloating; - c->animation_type = r->animation_type; - c->isnoborder = r->isnoborder; - newtags |= r->tags; - i = 0; - wl_list_for_each(m, &mons, link) - if (r->monitor == i++) - mon = m; - - if(c->isfloating && r->width != 0 && r->height != 0){ - c->geom.width = r->width; - c->geom.height = r->height; - //重新计算居中的坐标 - c->geom = setclient_coordinate_center(c->geom); - } - if(r->isfullscreen){ - c->isfullscreen =1; - c->ignore_clear_fullscreen = 1; - } - break; - } - } + for (r = rules; r < END(rules); r++) { + if ((!r->title || strstr(title, r->title)) && + (!r->id || strstr(appid, r->id))) { + c->isfloating = r->isfloating; + c->animation_type = r->animation_type; + c->isnoborder = r->isnoborder; + newtags |= r->tags; + i = 0; + wl_list_for_each(m, &mons, link) if (r->monitor == i++) mon = m; - wlr_scene_node_reparent(&c->scene->node, layers[c->isfloating ? LyrFloat : LyrTile]); - setmon(c, mon, newtags); + if (c->isfloating && r->width != 0 && r->height != 0) { + c->geom.width = r->width; + c->geom.height = r->height; + // 重新计算居中的坐标 + c->geom = setclient_coordinate_center(c->geom); + } + if (r->isfullscreen) { + c->isfullscreen = 1; + c->ignore_clear_fullscreen = 1; + } + break; + } + } - Client *fc; - // 如果当前的tag中有新创建的非悬浮窗口,就让当前tag中的全屏窗口退出全屏参与平铺 - wl_list_for_each(fc, &clients, link) - if (fc && !c->ignore_clear_fullscreen && c->tags & fc->tags && ISFULLSCREEN(fc) && !c->isfloating ) { - clear_fullscreen_flag(fc); - arrange(c->mon,false); - }else if(c->ignore_clear_fullscreen && c->isfullscreen){ - setfullscreen(c,1); - } + wlr_scene_node_reparent(&c->scene->node, + layers[c->isfloating ? LyrFloat : LyrTile]); + setmon(c, mon, newtags); - if(!(c->tags & ( 1 << (selmon->pertag->curtag - 1) ))){ - c->animation.from_rule = true; - view(&(Arg){.ui = c->tags},true); - } + Client *fc; + // 如果当前的tag中有新创建的非悬浮窗口,就让当前tag中的全屏窗口退出全屏参与平铺 + wl_list_for_each(fc, &clients, link) if (fc && !c->ignore_clear_fullscreen && + c->tags & fc->tags && + ISFULLSCREEN(fc) && !c->isfloating) { + clear_fullscreen_flag(fc); + arrange(c->mon, false); + } + else if (c->ignore_clear_fullscreen && c->isfullscreen) { + setfullscreen(c, 1); + } + + if (!(c->tags & (1 << (selmon->pertag->curtag - 1)))) { + c->animation.from_rule = true; + view(&(Arg){.ui = c->tags}, true); + } } -void //17 -arrange(Monitor *m,bool want_animation) -{ - Client *c; +void // 17 +arrange(Monitor *m, bool want_animation) { + Client *c; - if (!m->wlr_output->enabled) - return; + if (!m->wlr_output->enabled) + return; - 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); - client_set_suspended(c, false); - if (!c->animation.from_rule && want_animation && m->pertag->prevtag !=0 && m->pertag->curtag !=0) { - c->animation.tagining = true; - if (m->pertag->curtag > m->pertag->prevtag) { - c->animainit_geom.x = c->geom.x + c->mon->m.width -(c->geom.x -c->mon->m.x); - } else { - c->animainit_geom.x = m->m.x - c->geom.width; - } - } + 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); + client_set_suspended(c, false); + if (!c->animation.from_rule && want_animation && + m->pertag->prevtag != 0 && m->pertag->curtag != 0) { + c->animation.tagining = true; + if (m->pertag->curtag > m->pertag->prevtag) { + c->animainit_geom.x = + c->geom.x + c->mon->m.width - (c->geom.x - c->mon->m.x); + } else { + c->animainit_geom.x = m->m.x - c->geom.width; + } + } - c->animation.from_rule = false; - if((c->isfloating || c->isfullscreen || c->isfakefullscreen) && (c->animation.tagouting || c->animation.tagouted)) { - c->animation.tagouting = false; - c->animation.tagouted = false; - resize(c,c->geom,0); - } else { - c->animation.tagouting = false; - c->animation.tagouted = false; - resize(c,c->geom,0); - } - } else { - if ((c->tags & ( 1 << (selmon->pertag->prevtag - 1) )) && want_animation && m->pertag->prevtag != 0 && m->pertag->curtag !=0) { - c->animation.tagouting = true; - if (m->pertag->curtag > m->pertag->prevtag) { - c->pending = c->geom; - c->pending.x -= c->geom.x + m->m.width; - resize(c,c->geom,0); - } else { - c->pending = c->geom; - c->pending.x -= c->geom.x - m->m.width; - resize(c,c->geom,0); - } - } else { - wlr_scene_node_set_enabled(&c->scene->node, false); - client_set_suspended(c, true); - } - } + c->animation.from_rule = false; + if ((c->isfloating || c->isfullscreen || c->isfakefullscreen) && + (c->animation.tagouting || c->animation.tagouted)) { + c->animation.tagouting = false; + c->animation.tagouted = false; + resize(c, c->geom, 0); + } else { + c->animation.tagouting = false; + c->animation.tagouted = false; + resize(c, c->geom, 0); + } + } else { + if ((c->tags & (1 << (selmon->pertag->prevtag - 1))) && + want_animation && m->pertag->prevtag != 0 && + m->pertag->curtag != 0) { + c->animation.tagouting = true; + if (m->pertag->curtag > m->pertag->prevtag) { + c->pending = c->geom; + c->pending.x -= c->geom.x + m->m.width; + resize(c, c->geom, 0); + } else { + c->pending = c->geom; + c->pending.x -= c->geom.x - m->m.width; + resize(c, c->geom, 0); + } + } else { + wlr_scene_node_set_enabled(&c->scene->node, false); + client_set_suspended(c, true); + } + } + } + } - } - } + // 给全屏窗口设置背景为黑色 + // 好像要跟LyrFS图层一起使用,我不用这个图层,所以注释掉 + // wlr_scene_node_set_enabled(&m->fullscreen_bg->node, + // (c = focustop(m)) && c->isfullscreen); - // 给全屏窗口设置背景为黑色 好像要跟LyrFS图层一起使用,我不用这个图层,所以注释掉 - // wlr_scene_node_set_enabled(&m->fullscreen_bg->node, - // (c = focustop(m)) && c->isfullscreen); + if (m->isoverview) { + overviewlayout.arrange(m, 0, 0); + } else if (m && m->lt[m->sellt]->arrange) { + m->lt[m->sellt]->arrange(m, gappoh, 0); + } - - - if(m->isoverview){ - overviewlayout.arrange(m,0,0); - }else if (m && m->lt[m->sellt]->arrange){ - m->lt[m->sellt]->arrange(m,gappoh,0); - } - - #ifdef IM - if (input_relay && input_relay->popup) - input_popup_update(input_relay->popup); - #endif - motionnotify(0, NULL, 0, 0, 0, 0); - checkidleinhibitor(NULL); +#ifdef IM + if (input_relay && input_relay->popup) + input_popup_update(input_relay->popup); +#endif + motionnotify(0, NULL, 0, 0, 0, 0); + checkidleinhibitor(NULL); } -void //0.5 -arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int exclusive) -{ - LayerSurface *l; - struct wlr_box full_area = m->m; +void // 0.5 +arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, + int exclusive) { + LayerSurface *l; + struct wlr_box full_area = m->m; - wl_list_for_each(l, list, link) { - struct wlr_layer_surface_v1 *layer_surface = l->layer_surface; + wl_list_for_each(l, list, link) { + struct wlr_layer_surface_v1 *layer_surface = l->layer_surface; - if (exclusive != (layer_surface->current.exclusive_zone > 0)) - continue; + if (exclusive != (layer_surface->current.exclusive_zone > 0)) + continue; - wlr_scene_layer_surface_v1_configure(l->scene_layer, &full_area, usable_area); - wlr_scene_node_set_position(&l->popups->node, l->scene->node.x, l->scene->node.y); - l->geom.x = l->scene->node.x; - l->geom.y = l->scene->node.y; - } + wlr_scene_layer_surface_v1_configure(l->scene_layer, &full_area, + usable_area); + wlr_scene_node_set_position(&l->popups->node, l->scene->node.x, + l->scene->node.y); + l->geom.x = l->scene->node.x; + l->geom.y = l->scene->node.y; + } } Client *direction_select(const Arg *arg) { - Client *c,*tempClients[100]; - Client *tc = selmon->sel; - int last = -1; + Client *c, *tempClients[100]; + Client *tc = selmon->sel; + int last = -1; - if(!tc) - return NULL; + if (!tc) + return NULL; - if (tc && - (tc->isfullscreen || tc->isfakefullscreen)) /* no support for focusstack with fullscreen windows */ - return NULL; + if (tc && + (tc->isfullscreen || tc->isfakefullscreen)) /* no support for focusstack + with fullscreen windows */ + return NULL; - wl_list_for_each(c, &clients, link) - if (c && (c->tags & c->mon->tagset[c->mon->seltags])){ - last++; - tempClients[last] = c; - } - if (last < 0) - return NULL; - int sel_x = tc->geom.x; - int sel_y = tc->geom.y; - long long int distance = LLONG_MAX; - // int temp_focus = 0; - Client *tempFocusClients = NULL; + wl_list_for_each(c, &clients, + link) if (c && (c->tags & c->mon->tagset[c->mon->seltags])) { + last++; + tempClients[last] = c; + } + if (last < 0) + return NULL; + int sel_x = tc->geom.x; + int sel_y = tc->geom.y; + long long int distance = LLONG_MAX; + // int temp_focus = 0; + Client *tempFocusClients = NULL; - switch (arg->i) { - case UP: - for (int _i = 0; _i <= last; _i++) { - if (tempClients[_i]->geom.y < sel_y && tempClients[_i]->geom.x == sel_x) { - int dis_x = tempClients[_i]->geom.x - sel_x; - int dis_y = tempClients[_i]->geom.y - sel_y; - long long int tmp_distance = dis_x * dis_x + dis_y * dis_y; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; - } - } - } - if (!tempFocusClients) { - for (int _i = 0; _i <= last; _i++) { - if (tempClients[_i]->geom.y < sel_y ) { - int dis_x = tempClients[_i]->geom.x - sel_x; - int dis_y = tempClients[_i]->geom.y - sel_y; - long long int tmp_distance = dis_x * dis_x + dis_y * dis_y; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; - } - } - } - } - break; - case DOWN: - for (int _i = 0; _i <= last; _i++) { - if (tempClients[_i]->geom.y > sel_y && tempClients[_i]->geom.x == sel_x) { - int dis_x = tempClients[_i]->geom.x - sel_x; - int dis_y = tempClients[_i]->geom.y - sel_y; - long long int tmp_distance = dis_x * dis_x + dis_y * dis_y; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; - } - } - } - if (!tempFocusClients) { - for (int _i = 0; _i <= last; _i++) { - if (tempClients[_i]->geom.y > sel_y ) { - int dis_x = tempClients[_i]->geom.x - sel_x; - int dis_y = tempClients[_i]->geom.y - sel_y; - long long int tmp_distance = dis_x * dis_x + dis_y * dis_y; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; - } - } - } - } - break; - case LEFT: - for (int _i = 0; _i <= last; _i++) { - if (tempClients[_i]->geom.x < sel_x && tempClients[_i]->geom.y == sel_y) { - int dis_x = tempClients[_i]->geom.x - sel_x; - int dis_y = tempClients[_i]->geom.y - sel_y; - long long int tmp_distance = dis_x * dis_x + dis_y * dis_y; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; - } - } - } - if(!tempFocusClients) { - for (int _i = 0; _i <= last; _i++) { - if (tempClients[_i]->geom.x < sel_x ) { - int dis_x = tempClients[_i]->geom.x - sel_x; - int dis_y = tempClients[_i]->geom.y - sel_y; - long long int tmp_distance = dis_x * dis_x + dis_y * dis_y; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; - } - } - } - } - break; - case RIGHT: - for (int _i = 0; _i <= last; _i++) { - if (tempClients[_i]->geom.x > sel_x && tempClients[_i]->geom.y == sel_y) { - int dis_x = tempClients[_i]->geom.x - sel_x; - int dis_y = tempClients[_i]->geom.y - sel_y; - long long int tmp_distance = dis_x * dis_x + dis_y * dis_y; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; - } - } - } - if(!tempFocusClients) { - for (int _i = 0; _i <= last; _i++) { - if (tempClients[_i]->geom.x > sel_x ) { - int dis_x = tempClients[_i]->geom.x - sel_x; - int dis_y = tempClients[_i]->geom.y - sel_y; - long long int tmp_distance = dis_x * dis_x + dis_y * dis_y; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; - } - } - } - } - break; - } - return tempFocusClients; + switch (arg->i) { + case UP: + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->geom.y < sel_y && tempClients[_i]->geom.x == sel_x) { + int dis_x = tempClients[_i]->geom.x - sel_x; + int dis_y = tempClients[_i]->geom.y - sel_y; + long long int tmp_distance = dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + if (!tempFocusClients) { + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->geom.y < sel_y) { + int dis_x = tempClients[_i]->geom.x - sel_x; + int dis_y = tempClients[_i]->geom.y - sel_y; + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + } + break; + case DOWN: + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->geom.y > sel_y && tempClients[_i]->geom.x == sel_x) { + int dis_x = tempClients[_i]->geom.x - sel_x; + int dis_y = tempClients[_i]->geom.y - sel_y; + long long int tmp_distance = dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + if (!tempFocusClients) { + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->geom.y > sel_y) { + int dis_x = tempClients[_i]->geom.x - sel_x; + int dis_y = tempClients[_i]->geom.y - sel_y; + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + } + break; + case LEFT: + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->geom.x < sel_x && tempClients[_i]->geom.y == sel_y) { + int dis_x = tempClients[_i]->geom.x - sel_x; + int dis_y = tempClients[_i]->geom.y - sel_y; + long long int tmp_distance = dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + if (!tempFocusClients) { + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->geom.x < sel_x) { + int dis_x = tempClients[_i]->geom.x - sel_x; + int dis_y = tempClients[_i]->geom.y - sel_y; + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + } + break; + case RIGHT: + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->geom.x > sel_x && tempClients[_i]->geom.y == sel_y) { + int dis_x = tempClients[_i]->geom.x - sel_x; + int dis_y = tempClients[_i]->geom.y - sel_y; + long long int tmp_distance = dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + if (!tempFocusClients) { + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->geom.x > sel_x) { + int dis_x = tempClients[_i]->geom.x - sel_x; + int dis_y = tempClients[_i]->geom.y - sel_y; + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + } + break; + } + return tempFocusClients; } void focusdir(const Arg *arg) { - Client *c; - c = direction_select(arg); - if(c) { - focusclient(c,1); - if(warpcursor) - warp_cursor(c); - } -} - -void //0.5 -arrangelayers(Monitor *m) -{ - int i; - struct wlr_box usable_area = m->m; - LayerSurface *l; - uint32_t layers_above_shell[] = { - ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, - ZWLR_LAYER_SHELL_V1_LAYER_TOP, - }; - if (!m->wlr_output->enabled) - return; - - /* Arrange exclusive surfaces from top->bottom */ - for (i = 3; i >= 0; i--) - arrangelayer(m, &m->layers[i], &usable_area, 1); - - if (!wlr_box_equal(&usable_area, &m->w)) { - m->w = usable_area; - arrange(m,false); - } - - /* Arrange non-exlusive surfaces from top->bottom */ - for (i = 3; i >= 0; i--) - arrangelayer(m, &m->layers[i], &usable_area, 0); - - /* Find topmost keyboard interactive layer, if such a layer exists */ - for (i = 0; i < (int)LENGTH(layers_above_shell); i++) { - wl_list_for_each_reverse(l, &m->layers[layers_above_shell[i]], link) { - if (locked || !l->layer_surface->current.keyboard_interactive || !l->mapped) - continue; - /* Deactivate the focused client. */ - focusclient(NULL, 0); - exclusive_focus = l; - client_notify_enter(l->layer_surface->surface, wlr_seat_get_keyboard(seat)); - return; - } - } -} - -void -autostartexec(void) { - const char *const *p; - size_t i = 0; - - /* count entries */ - for (p = autostart; *p; autostart_len++, p++) - while (*++p); - - autostart_pids = calloc(autostart_len, sizeof(pid_t)); - for (p = autostart; *p; i++, p++) { - if ((autostart_pids[i] = fork()) == 0) { - setsid(); - execvp(*p, (char *const *)p); - die("dwl: execvp %s:", *p); - } - /* skip arguments */ - while (*++p); - } -} - -void //鼠标滚轮事件 -axisnotify(struct wl_listener *listener, void *data) -{ - - - /* This event is forwarded by the cursor when a pointer emits an axis event, - * for example when you move the scroll wheel. */ - struct wlr_pointer_axis_event *event = data; - struct wlr_keyboard *keyboard; - uint32_t mods; - const Axis *a; - unsigned int adir; - // IDLE_NOTIFY_ACTIVITY; - wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); - keyboard = wlr_seat_get_keyboard(seat); - - //获取当前按键的mask,比如alt+super或者alt+ctrl - mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; - - if (event->orientation == WLR_AXIS_ORIENTATION_VERTICAL) - adir = event->delta > 0 ? AxisDown : AxisUp; - else - adir = event->delta > 0 ? AxisRight : AxisLeft; - - for (a = axes; a < END(axes); a++) { - if (CLEANMASK(mods) == CLEANMASK(a->mod) && //按键一致 - adir == a->dir && a->func) { //滚轮方向判断一致且处理函数存在 - if (event->time_msec - axis_apply_time > axis_bind_apply_timeout) { - a->func(&a->arg); - axis_apply_time = event->time_msec; - return; //如果成功匹配就不把这个滚轮事件传送给客户端了 - } else { - axis_apply_time = event->time_msec; - return; - } - - } - } - - /* TODO: allow usage of scroll whell for mousebindings, it can be implemented - * checking the event's orientation and the delta of the event */ - /* Notify the client with pointer focus of the axis event. */ - wlr_seat_pointer_notify_axis(seat, //滚轮事件发送给客户端也就是窗口 - event->time_msec, event->orientation, event->delta, - event->delta_discrete, event->source); - - -} - -void //鼠标按键事件 -buttonpress(struct wl_listener *listener, void *data) -{ - struct wlr_pointer_button_event *event = data; - struct wlr_keyboard *keyboard; - uint32_t mods; - Client *c; - const Button *b; - // IDLE_NOTIFY_ACTIVITY; - wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); - - switch (event->state) { - case WLR_BUTTON_PRESSED: - cursor_mode = CurPressed; - selmon = xytomon(cursor->x, cursor->y); - if (locked) - break; - - /* Change focus if the button was _pressed_ over a client */ - xytonode(cursor->x, cursor->y, NULL, &c, NULL, NULL, NULL); - if (c && (!client_is_unmanaged(c) || client_wants_focus(c))) - focusclient(c, 1); - - keyboard = wlr_seat_get_keyboard(seat); - mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; - for (b = buttons; b < END(buttons); b++) { - if (CLEANMASK(mods) == CLEANMASK(b->mod) && - event->button == b->button && b->func && (selmon->isoverview == 1 || b->button == BTN_MIDDLE ) && c) { - b->func(&b->arg); - return; - } else if (CLEANMASK(mods) == CLEANMASK(b->mod) && - event->button == b->button && b->func && CLEANMASK(b->mod) != 0 ) { - b->func(&b->arg); - return; - - } - } - break; - case WLR_BUTTON_RELEASED: - /* If you released any buttons, we exit interactive move/resize mode. */ - if (!locked && cursor_mode != CurNormal && cursor_mode != CurPressed) { - cursor_mode = CurNormal; - /* Clear the pointer focus, this way if the cursor is over a surface - * we will send an enter event after which the client will provide us - * a cursor surface */ - wlr_seat_pointer_clear_focus(seat); - motionnotify(0, NULL, 0, 0, 0, 0); - /* Drop the window off on its new monitor */ - selmon = xytomon(cursor->x, cursor->y); - setmon(grabc, selmon, 0); - grabc = NULL; - return; - } else { - cursor_mode = CurNormal; - } - break; - } - /* If the event wasn't handled by the compositor, notify the client with - * pointer focus that a button press has occurred */ - wlr_seat_pointer_notify_button(seat, - event->time_msec, event->button, event->state); -} - -void //0.5 -chvt(const Arg *arg) -{ - wlr_session_change_vt(session, arg->ui); + Client *c; + c = direction_select(arg); + if (c) { + focusclient(c, 1); + if (warpcursor) + warp_cursor(c); + } } void // 0.5 -checkidleinhibitor(struct wlr_surface *exclude) -{ - int inhibited = 0, unused_lx, unused_ly; - struct wlr_idle_inhibitor_v1 *inhibitor; - wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) { - struct wlr_surface *surface = wlr_surface_get_root_surface(inhibitor->surface); - struct wlr_scene_tree *tree = surface->data; - if (exclude != surface && (bypass_surface_visibility || (!tree - || wlr_scene_node_coords(&tree->node, &unused_lx, &unused_ly)))) { - inhibited = 1; - break; - } - } +arrangelayers(Monitor *m) { + int i; + struct wlr_box usable_area = m->m; + LayerSurface *l; + uint32_t layers_above_shell[] = { + ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, + ZWLR_LAYER_SHELL_V1_LAYER_TOP, + }; + if (!m->wlr_output->enabled) + return; - wlr_idle_notifier_v1_set_inhibited(idle_notifier, inhibited); + /* Arrange exclusive surfaces from top->bottom */ + for (i = 3; i >= 0; i--) + arrangelayer(m, &m->layers[i], &usable_area, 1); + + if (!wlr_box_equal(&usable_area, &m->w)) { + m->w = usable_area; + arrange(m, false); + } + + /* Arrange non-exlusive surfaces from top->bottom */ + for (i = 3; i >= 0; i--) + arrangelayer(m, &m->layers[i], &usable_area, 0); + + /* Find topmost keyboard interactive layer, if such a layer exists */ + for (i = 0; i < (int)LENGTH(layers_above_shell); i++) { + wl_list_for_each_reverse(l, &m->layers[layers_above_shell[i]], link) { + if (locked || !l->layer_surface->current.keyboard_interactive || + !l->mapped) + continue; + /* Deactivate the focused client. */ + focusclient(NULL, 0); + exclusive_focus = l; + client_notify_enter(l->layer_surface->surface, + wlr_seat_get_keyboard(seat)); + return; + } + } } -void //0.5 -setcursorshape(struct wl_listener *listener, void *data) -{ - struct wlr_cursor_shape_manager_v1_request_set_shape_event *event = data; - if (cursor_mode != CurNormal && cursor_mode != CurPressed) - return; - /* This can be sent by any client, so we check to make sure this one is - * actually has pointer focus first. If so, we can tell the cursor to - * use the provided cursor shape. */ - if (event->seat_client == seat->pointer_state.focused_client) - wlr_cursor_set_xcursor(cursor, cursor_mgr, - wlr_cursor_shape_v1_name(event->shape)); +void autostartexec(void) { + const char *const *p; + size_t i = 0; + + /* count entries */ + for (p = autostart; *p; autostart_len++, p++) + while (*++p) + ; + + autostart_pids = calloc(autostart_len, sizeof(pid_t)); + for (p = autostart; *p; i++, p++) { + if ((autostart_pids[i] = fork()) == 0) { + setsid(); + execvp(*p, (char *const *)p); + die("dwl: execvp %s:", *p); + } + /* skip arguments */ + while (*++p) + ; + } } +void // 鼠标滚轮事件 +axisnotify(struct wl_listener *listener, void *data) { -void //17 -cleanup(void) -{ + /* This event is forwarded by the cursor when a pointer emits an axis event, + * for example when you move the scroll wheel. */ + struct wlr_pointer_axis_event *event = data; + struct wlr_keyboard *keyboard; + uint32_t mods; + const Axis *a; + unsigned int adir; + // IDLE_NOTIFY_ACTIVITY; + wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); + keyboard = wlr_seat_get_keyboard(seat); + + // 获取当前按键的mask,比如alt+super或者alt+ctrl + mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; + + if (event->orientation == WLR_AXIS_ORIENTATION_VERTICAL) + adir = event->delta > 0 ? AxisDown : AxisUp; + else + adir = event->delta > 0 ? AxisRight : AxisLeft; + + for (a = axes; a < END(axes); a++) { + if (CLEANMASK(mods) == CLEANMASK(a->mod) && // 按键一致 + adir == a->dir && a->func) { // 滚轮方向判断一致且处理函数存在 + if (event->time_msec - axis_apply_time > axis_bind_apply_timeout) { + a->func(&a->arg); + axis_apply_time = event->time_msec; + return; // 如果成功匹配就不把这个滚轮事件传送给客户端了 + } else { + axis_apply_time = event->time_msec; + return; + } + } + } + + /* TODO: allow usage of scroll whell for mousebindings, it can be implemented + * checking the event's orientation and the delta of the event */ + /* Notify the client with pointer focus of the axis event. */ + wlr_seat_pointer_notify_axis(seat, // 滚轮事件发送给客户端也就是窗口 + event->time_msec, event->orientation, + event->delta, event->delta_discrete, + event->source); +} + +void // 鼠标按键事件 +buttonpress(struct wl_listener *listener, void *data) { + struct wlr_pointer_button_event *event = data; + struct wlr_keyboard *keyboard; + uint32_t mods; + Client *c; + const Button *b; + // IDLE_NOTIFY_ACTIVITY; + wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); + + switch (event->state) { + case WLR_BUTTON_PRESSED: + cursor_mode = CurPressed; + selmon = xytomon(cursor->x, cursor->y); + if (locked) + break; + + /* Change focus if the button was _pressed_ over a client */ + xytonode(cursor->x, cursor->y, NULL, &c, NULL, NULL, NULL); + if (c && (!client_is_unmanaged(c) || client_wants_focus(c))) + focusclient(c, 1); + + keyboard = wlr_seat_get_keyboard(seat); + mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; + for (b = buttons; b < END(buttons); b++) { + if (CLEANMASK(mods) == CLEANMASK(b->mod) && event->button == b->button && + b->func && (selmon->isoverview == 1 || b->button == BTN_MIDDLE) && + c) { + b->func(&b->arg); + return; + } else if (CLEANMASK(mods) == CLEANMASK(b->mod) && + event->button == b->button && b->func && + CLEANMASK(b->mod) != 0) { + b->func(&b->arg); + return; + } + } + break; + case WLR_BUTTON_RELEASED: + /* If you released any buttons, we exit interactive move/resize mode. */ + if (!locked && cursor_mode != CurNormal && cursor_mode != CurPressed) { + cursor_mode = CurNormal; + /* Clear the pointer focus, this way if the cursor is over a surface + * we will send an enter event after which the client will provide us + * a cursor surface */ + wlr_seat_pointer_clear_focus(seat); + motionnotify(0, NULL, 0, 0, 0, 0); + /* Drop the window off on its new monitor */ + selmon = xytomon(cursor->x, cursor->y); + setmon(grabc, selmon, 0); + grabc = NULL; + return; + } else { + cursor_mode = CurNormal; + } + break; + } + /* If the event wasn't handled by the compositor, notify the client with + * pointer focus that a button press has occurred */ + wlr_seat_pointer_notify_button(seat, event->time_msec, event->button, + event->state); +} + +void // 0.5 +chvt(const Arg *arg) { + wlr_session_change_vt(session, arg->ui); +} + +void // 0.5 +checkidleinhibitor(struct wlr_surface *exclude) { + int inhibited = 0, unused_lx, unused_ly; + struct wlr_idle_inhibitor_v1 *inhibitor; + wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) { + struct wlr_surface *surface = + wlr_surface_get_root_surface(inhibitor->surface); + struct wlr_scene_tree *tree = surface->data; + if (exclude != surface && + (bypass_surface_visibility || + (!tree || + wlr_scene_node_coords(&tree->node, &unused_lx, &unused_ly)))) { + inhibited = 1; + break; + } + } + + wlr_idle_notifier_v1_set_inhibited(idle_notifier, inhibited); +} + +void // 0.5 +setcursorshape(struct wl_listener *listener, void *data) { + struct wlr_cursor_shape_manager_v1_request_set_shape_event *event = data; + if (cursor_mode != CurNormal && cursor_mode != CurPressed) + return; + /* This can be sent by any client, so we check to make sure this one is + * actually has pointer focus first. If so, we can tell the cursor to + * use the provided cursor shape. */ + if (event->seat_client == seat->pointer_state.focused_client) + wlr_cursor_set_xcursor(cursor, cursor_mgr, + wlr_cursor_shape_v1_name(event->shape)); +} + +void // 17 +cleanup(void) { #ifdef XWAYLAND - wlr_xwayland_destroy(xwayland); + wlr_xwayland_destroy(xwayland); #endif - wl_display_destroy_clients(dpy); - if (child_pid > 0) { - kill(child_pid, SIGTERM); - waitpid(child_pid, NULL, 0); - } - wlr_backend_destroy(backend); - wlr_scene_node_destroy(&scene->tree.node); - wlr_renderer_destroy(drw); - wlr_allocator_destroy(alloc); - wlr_xcursor_manager_destroy(cursor_mgr); - wlr_cursor_destroy(cursor); - wlr_output_layout_destroy(output_layout); - wlr_seat_destroy(seat); - wl_display_destroy(dpy); + wl_display_destroy_clients(dpy); + if (child_pid > 0) { + kill(child_pid, SIGTERM); + waitpid(child_pid, NULL, 0); + } + wlr_backend_destroy(backend); + wlr_scene_node_destroy(&scene->tree.node); + wlr_renderer_destroy(drw); + wlr_allocator_destroy(alloc); + wlr_xcursor_manager_destroy(cursor_mgr); + wlr_cursor_destroy(cursor); + wlr_output_layout_destroy(output_layout); + wlr_seat_destroy(seat); + wl_display_destroy(dpy); } -void //17 -cleanupkeyboard(struct wl_listener *listener, void *data) -{ - Keyboard *kb = wl_container_of(listener, kb, destroy); +void // 17 +cleanupkeyboard(struct wl_listener *listener, void *data) { + Keyboard *kb = wl_container_of(listener, kb, destroy); - wl_event_source_remove(kb->key_repeat_source); - wl_list_remove(&kb->link); - wl_list_remove(&kb->modifiers.link); - wl_list_remove(&kb->key.link); - wl_list_remove(&kb->destroy.link); - free(kb); + wl_event_source_remove(kb->key_repeat_source); + wl_list_remove(&kb->link); + wl_list_remove(&kb->modifiers.link); + wl_list_remove(&kb->key.link); + wl_list_remove(&kb->destroy.link); + free(kb); } -void //0.5 -cleanupmon(struct wl_listener *listener, void *data) -{ - Monitor *m = wl_container_of(listener, m, destroy); - LayerSurface *l, *tmp; - size_t i; +void // 0.5 +cleanupmon(struct wl_listener *listener, void *data) { + Monitor *m = wl_container_of(listener, m, destroy); + LayerSurface *l, *tmp; + size_t i; - /* m->layers[i] are intentionally not unlinked */ - for (i = 0; i < LENGTH(m->layers); i++) { - wl_list_for_each_safe(l, tmp, &m->layers[i], link) - wlr_layer_surface_v1_destroy(l->layer_surface); - } + /* m->layers[i] are intentionally not unlinked */ + for (i = 0; i < LENGTH(m->layers); i++) { + wl_list_for_each_safe(l, tmp, &m->layers[i], link) + wlr_layer_surface_v1_destroy(l->layer_surface); + } - wl_list_remove(&m->destroy.link); - wl_list_remove(&m->frame.link); - wl_list_remove(&m->link); - wl_list_remove(&m->request_state.link); - m->wlr_output->data = NULL; - wlr_output_layout_remove(output_layout, m->wlr_output); - wlr_scene_output_destroy(m->scene_output); + wl_list_remove(&m->destroy.link); + wl_list_remove(&m->frame.link); + wl_list_remove(&m->link); + wl_list_remove(&m->request_state.link); + m->wlr_output->data = NULL; + wlr_output_layout_remove(output_layout, m->wlr_output); + wlr_scene_output_destroy(m->scene_output); - closemon(m); - // wlr_scene_node_destroy(&m->fullscreen_bg->node); - free(m); + closemon(m); + // wlr_scene_node_destroy(&m->fullscreen_bg->node); + free(m); } - -void -closemon(Monitor *m) //0.5 +void closemon(Monitor *m) // 0.5 { - /* update selmon if needed and - * move closed monitor's clients to the focused one */ - Client *c; - int i = 0, nmons = wl_list_length(&mons); - if (!nmons) { - selmon = NULL; - } else if (m == selmon) { - do /* don't switch to disabled mons */ - selmon = wl_container_of(mons.next, selmon, link); - while (!selmon->wlr_output->enabled && i++ < nmons); - } + /* update selmon if needed and + * move closed monitor's clients to the focused one */ + Client *c; + int i = 0, nmons = wl_list_length(&mons); + if (!nmons) { + selmon = NULL; + } else if (m == selmon) { + do /* don't switch to disabled mons */ + selmon = wl_container_of(mons.next, selmon, link); + while (!selmon->wlr_output->enabled && i++ < nmons); + } - wl_list_for_each(c, &clients, link) { - if (c->isfloating && c->geom.x > m->m.width) - resize(c, (struct wlr_box){.x = c->geom.x - m->w.width, .y = c->geom.y, - .width = c->geom.width, .height = c->geom.height}, 0); - if (c->mon == m) { - setmon(c, selmon, c->tags); - reset_foreign_tolevel(c); - } - } - focusclient(focustop(selmon), 1); - printstatus(); -} - -void //0.5 -commitlayersurfacenotify(struct wl_listener *listener, void *data) -{ - LayerSurface *l = wl_container_of(listener, l, surface_commit); - struct wlr_layer_surface_v1 *layer_surface = l->layer_surface; - struct wlr_scene_tree *scene_layer = layers[layermap[layer_surface->current.layer]]; - - if (layer_surface->current.committed == 0 && l->mapped == layer_surface->surface->mapped) - return; - l->mapped = layer_surface->surface->mapped; - - if (scene_layer != l->scene->node.parent) { - wlr_scene_node_reparent(&l->scene->node, scene_layer); - wl_list_remove(&l->link); - wl_list_insert(&l->mon->layers[layer_surface->current.layer], &l->link); - wlr_scene_node_reparent(&l->popups->node, (layer_surface->current.layer - < ZWLR_LAYER_SHELL_V1_LAYER_TOP ? layers[LyrTop] : scene_layer)); - } - - arrangelayers(l->mon); + wl_list_for_each(c, &clients, link) { + if (c->isfloating && c->geom.x > m->m.width) + resize(c, + (struct wlr_box){.x = c->geom.x - m->w.width, + .y = c->geom.y, + .width = c->geom.width, + .height = c->geom.height}, + 0); + if (c->mon == m) { + setmon(c, selmon, c->tags); + reset_foreign_tolevel(c); + } + } + focusclient(focustop(selmon), 1); + printstatus(); } -void client_set_pending_state(Client *c) -{ +void // 0.5 +commitlayersurfacenotify(struct wl_listener *listener, void *data) { + LayerSurface *l = wl_container_of(listener, l, surface_commit); + struct wlr_layer_surface_v1 *layer_surface = l->layer_surface; + struct wlr_scene_tree *scene_layer = + layers[layermap[layer_surface->current.layer]]; - // 判断是否需要动画 - if (animations && c->animation.tagining) { - c->animation.tagining = false; - c->animation.should_animate = true; - c->animation.initial = c->animainit_geom; - } else if (!animations || c == grabc || (!c->is_open_animation && wlr_box_equal(&c->current, &c->pending))) - { - c->animation.should_animate = false; - } else if (c->is_restoring_from_ov) { - c->is_restoring_from_ov = false; - c->animation.should_animate = false; - } - else - { - c->animation.should_animate = true; - c->animation.initial = c->animainit_geom; - } + if (layer_surface->current.committed == 0 && + l->mapped == layer_surface->surface->mapped) + return; + l->mapped = layer_surface->surface->mapped; - // 开始动画 - client_commit(c); - c->dirty = true; + if (scene_layer != l->scene->node.parent) { + wlr_scene_node_reparent(&l->scene->node, scene_layer); + wl_list_remove(&l->link); + wl_list_insert(&l->mon->layers[layer_surface->current.layer], &l->link); + wlr_scene_node_reparent( + &l->popups->node, + (layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP + ? layers[LyrTop] + : scene_layer)); + } + + arrangelayers(l->mon); } -double -output_frame_duration_ms(Client *c) { +void client_set_pending_state(Client *c) { + + // 判断是否需要动画 + if (animations && c->animation.tagining) { + c->animation.tagining = false; + c->animation.should_animate = true; + c->animation.initial = c->animainit_geom; + } else if (!animations || c == grabc || + (!c->is_open_animation && + wlr_box_equal(&c->current, &c->pending))) { + c->animation.should_animate = false; + } else if (c->is_restoring_from_ov) { + c->is_restoring_from_ov = false; + c->animation.should_animate = false; + } else { + c->animation.should_animate = true; + c->animation.initial = c->animainit_geom; + } + + // 开始动画 + client_commit(c); + c->dirty = true; +} + +double output_frame_duration_ms(Client *c) { return 1000000.0 / c->mon->wlr_output->refresh; } -void client_commit(Client *c) -{ - c->dirty = false; - c->current = c->pending; //设置动画的结束位置 +void client_commit(Client *c) { + c->dirty = false; + c->current = c->pending; // 设置动画的结束位置 - if (c->animation.should_animate) - { - // 设置动画速度 - c->animation.passed_frames = 0; - c->animation.total_frames = c->animation.duration / output_frame_duration_ms(c); + if (c->animation.should_animate) { + // 设置动画速度 + c->animation.passed_frames = 0; + c->animation.total_frames = + c->animation.duration / output_frame_duration_ms(c); - // 标记动画开始 - c->animation.running = true; - c->animation.should_animate = false; - } - // 请求刷新屏幕 - wlr_output_schedule_frame(c->mon->wlr_output); -} - -void //0.5 -commitnotify(struct wl_listener *listener, void *data) -{ - Client *c = wl_container_of(listener, c, commit); - // don't know need to do what... - return; -} - -void //0.5 -destroydecoration(struct wl_listener *listener, void *data) -{ - Client *c = wl_container_of(listener, c, destroy_decoration); - - wl_list_remove(&c->destroy_decoration.link); - wl_list_remove(&c->set_decoration_mode.link); - motionnotify(0, NULL, 0, 0, 0, 0); -} - - -void //0.5 -createdecoration(struct wl_listener *listener, void *data) -{ - struct wlr_xdg_toplevel_decoration_v1 *deco = data; - Client *c = deco->toplevel->base->data; - c->decoration = deco; - - LISTEN(&deco->events.request_mode, &c->set_decoration_mode, requestdecorationmode); - LISTEN(&deco->events.destroy, &c->destroy_decoration, destroydecoration); - - requestdecorationmode(&c->set_decoration_mode, deco); -} - - -void //0.5 -createidleinhibitor(struct wl_listener *listener, void *data) -{ - struct wlr_idle_inhibitor_v1 *idle_inhibitor = data; - LISTEN_STATIC(&idle_inhibitor->events.destroy, destroyidleinhibitor); - - checkidleinhibitor(NULL); -} - -void //17 -createkeyboard(struct wlr_keyboard *keyboard) -{ - struct xkb_context *context; - struct xkb_keymap *keymap; - Keyboard *kb = keyboard->data = ecalloc(1, sizeof(*kb)); - kb->wlr_keyboard = keyboard; - - /* Prepare an XKB keymap and assign it to the keyboard. */ - context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - keymap = xkb_keymap_new_from_names(context, &xkb_rules, - XKB_KEYMAP_COMPILE_NO_FLAGS); - - wlr_keyboard_set_keymap(keyboard, keymap); - xkb_keymap_unref(keymap); - xkb_context_unref(context); - wlr_keyboard_set_repeat_info(keyboard, repeat_rate, repeat_delay); - - if(numlockon == 1){ - uint32_t leds = 0 ; - xkb_mod_mask_t locked_mods = 0; - leds = leds | WLR_LED_NUM_LOCK; - //获取numlock所在的位置 - xkb_mod_index_t mod_index = xkb_map_mod_get_index(keymap, - XKB_MOD_NAME_NUM); - if (mod_index != XKB_MOD_INVALID) { - locked_mods |= (uint32_t)1 << mod_index; //将该位置设置为1,默认为0表示锁住小键盘 - } - //设置numlock为on - xkb_state_update_mask(keyboard->xkb_state, 0, 0, - locked_mods, 0, 0, 0); - wlr_keyboard_led_update(keyboard,leds); //将表示numlockon的灯打开 - } - - /* Here we set up listeners for keyboard events. */ - LISTEN(&keyboard->events.modifiers, &kb->modifiers, keypressmod); - LISTEN(&keyboard->events.key, &kb->key, keypress); - LISTEN(&keyboard->base.events.destroy, &kb->destroy, cleanupkeyboard); - - wlr_seat_set_keyboard(seat, keyboard); - - kb->key_repeat_source = wl_event_loop_add_timer( - wl_display_get_event_loop(dpy), keyrepeat, kb); - - /* And add the keyboard to our list of keyboards */ - wl_list_insert(&keyboards, &kb->link); -} - -void //0.5 -createlayersurface(struct wl_listener *listener, void *data) -{ - struct wlr_layer_surface_v1 *layer_surface = data; - LayerSurface *l; - struct wlr_surface *surface = layer_surface->surface; - struct wlr_scene_tree *scene_layer = layers[layermap[layer_surface->pending.layer]]; - struct wlr_layer_surface_v1_state old_state; - - if (!layer_surface->output - && !(layer_surface->output = selmon ? selmon->wlr_output : NULL)) { - wlr_layer_surface_v1_destroy(layer_surface); - return; - } - - l = layer_surface->data = ecalloc(1, sizeof(*l)); - l->type = LayerShell; - LISTEN(&surface->events.commit, &l->surface_commit, commitlayersurfacenotify); - LISTEN(&surface->events.map, &l->map, maplayersurfacenotify); - LISTEN(&surface->events.unmap, &l->unmap, unmaplayersurfacenotify); - LISTEN(&layer_surface->events.destroy, &l->destroy, destroylayersurfacenotify); - - l->layer_surface = layer_surface; - l->mon = layer_surface->output->data; - l->scene_layer = wlr_scene_layer_surface_v1_create(scene_layer, layer_surface); - l->scene = l->scene_layer->tree; - l->popups = surface->data = wlr_scene_tree_create(layer_surface->current.layer - < ZWLR_LAYER_SHELL_V1_LAYER_TOP ? layers[LyrTop] : scene_layer); - l->scene->node.data = l->popups->node.data = l; - - wl_list_insert(&l->mon->layers[layer_surface->pending.layer],&l->link); - wlr_surface_send_enter(surface, layer_surface->output); - - /* Temporarily set the layer's current state to pending - * so that we can easily arrange it - */ - old_state = layer_surface->current; - layer_surface->current = layer_surface->pending; - l->mapped = 1; - arrangelayers(l->mon); - layer_surface->current = old_state; -} - -void //0.5 -createlocksurface(struct wl_listener *listener, void *data) -{ - SessionLock *lock = wl_container_of(listener, lock, new_surface); - struct wlr_session_lock_surface_v1 *lock_surface = data; - Monitor *m = lock_surface->output->data; - struct wlr_scene_tree *scene_tree = lock_surface->surface->data - = wlr_scene_subsurface_tree_create(lock->scene, lock_surface->surface); - m->lock_surface = lock_surface; - - wlr_scene_node_set_position(&scene_tree->node, m->m.x, m->m.y); - wlr_session_lock_surface_v1_configure(lock_surface, m->m.width, m->m.height); - - LISTEN(&lock_surface->events.destroy, &m->destroy_lock_surface, destroylocksurface); - - if (m == selmon) - client_notify_enter(lock_surface->surface, wlr_seat_get_keyboard(seat)); -} - -void //17 need fix 0.5 -createmon(struct wl_listener *listener, void *data) -{ - /* This event is raised by the backend when a new output (aka a display or - * monitor) becomes available. */ - struct wlr_output *wlr_output = data; - const MonitorRule *r; - size_t i; - Monitor *m = wlr_output->data = ecalloc(1, sizeof(*m)); - m->wlr_output = wlr_output; - - wl_list_init(&m->dwl_ipc_outputs); - wlr_output_init_render(wlr_output, alloc, drw); - - /* Initialize monitor state using configured rules */ - for (i = 0; i < LENGTH(m->layers); i++) - wl_list_init(&m->layers[i]); - - m->gappih = gappih; - m->gappiv = gappiv; - m->gappoh = gappoh; - m->gappov = gappov; - m->isoverview = 0; - m->sel = NULL; - m->is_in_hotarea = 0; - m->tagset[0] = m->tagset[1] = 1; - float scale = 1; - m->mfact = default_mfact; - m->nmaster = default_nmaster; - enum wl_output_transform rr = WL_OUTPUT_TRANSFORM_NORMAL; - - if(LENGTH(layouts) > 1){ - m->lt[0] = &layouts[0]; //默认就有两个布局 - m->lt[1] = &layouts[1]; - }else{ - m->lt[0] = m->lt[1] = &layouts[0]; - } - for (r = monrules; r < END(monrules); r++) { - if (!r->name || strstr(wlr_output->name, r->name)) { - m->mfact = r->mfact; - m->nmaster = r->nmaster; - m->m.x = r->x; - m->m.y = r->y; - if(r->lt) - m->lt[0] = m->lt[1] = r->lt; - scale = r->scale; - rr = r->rr; - break; - } - } - - wlr_output_set_scale(wlr_output,scale); - wlr_xcursor_manager_load(cursor_mgr, scale); - wlr_output_set_transform(wlr_output, rr); - /* The mode is a tuple of (width, height, refresh rate), and each - * monitor supports only a specific set of modes. We just pick the - * monitor's preferred mode; a more sophisticated compositor would let - * the user configure it. */ - wlr_output_set_mode(wlr_output, wlr_output_preferred_mode(wlr_output)); - - /* Set up event listeners */ - LISTEN(&wlr_output->events.frame, &m->frame, rendermon); - LISTEN(&wlr_output->events.destroy, &m->destroy, cleanupmon); - LISTEN(&wlr_output->events.request_state, &m->request_state, requestmonstate); - - wlr_output_enable(wlr_output, 1); - if (!wlr_output_commit(wlr_output)) - return; - - /* Try to enable adaptive sync, note that not all monitors support it. - * wlr_output_commit() will deactivate it in case it cannot be enabled */ - wlr_output_enable_adaptive_sync(wlr_output, 1); - wlr_output_commit(wlr_output); - - wl_list_insert(&mons, &m->link); - printstatus(); - - m->pertag = calloc(1, sizeof(Pertag)); - m->pertag->curtag = m->pertag->prevtag = 1; - - for (i = 0; i <= LENGTH(tags); i++) { - m->pertag->nmasters[i] = m->nmaster; - m->pertag->mfacts[i] = m->mfact; - - m->pertag->ltidxs[i][0] = m->lt[0]; - m->pertag->ltidxs[i][1] = m->lt[1]; - m->pertag->sellts[i] = m->sellt; - } - - - /* The xdg-protocol specifies: - * - * If the fullscreened surface is not opaque, the compositor must make - * sure that other screen content not part of the same surface tree (made - * up of subsurfaces, popups or similarly coupled surfaces) are not - * visible below the fullscreened surface. - * - */ - /* updatemons() will resize and set correct position */ - // m->fullscreen_bg = wlr_scene_rect_create(layers[LyrFS], 0, 0, fullscreen_bg); - // wlr_scene_node_set_enabled(&m->fullscreen_bg->node, 0); - - /* Adds this to the output layout in the order it was configured in. - * - * The output layout utility automatically adds a wl_output global to the - * display, which Wayland clients can see to find out information about the - * output (such as DPI, scale factor, manufacturer, etc). - */ - m->scene_output = wlr_scene_output_create(scene, wlr_output); - if (m->m.x < 0 || m->m.y < 0) - wlr_output_layout_add_auto(output_layout, wlr_output); - else - wlr_output_layout_add(output_layout, wlr_output, m->m.x, m->m.y); - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol)); -} - - - -void //fix for 0.5 -createnotify(struct wl_listener *listener, void *data) -{ - /* This event is raised when wlr_xdg_shell receives a new xdg surface from a - * client, either a toplevel (application window) or popup, - * or when wlr_layer_shell receives a new popup from a layer. - * If you want to do something tricky with popups you should check if - * its parent is wlr_xdg_shell or wlr_layer_shell */ - struct wlr_xdg_surface *xdg_surface = data; - Client *c = NULL; - LayerSurface *l = NULL; - - if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { - struct wlr_xdg_popup *popup = xdg_surface->popup; - struct wlr_box box; - if (toplevel_from_wlr_surface(popup->base->surface, &c, &l) < 0) - return; - popup->base->surface->data = wlr_scene_xdg_surface_create( - popup->parent->data, popup->base); - if ((l && !l->mon) || (c && !c->mon)) - return; - box = l ? l->mon->m : c->mon->w; - box.x -= (l ? l->geom.x : c->geom.x); - box.y -= (l ? l->geom.y : c->geom.y); - wlr_xdg_popup_unconstrain_from_box(popup, &box); - return; - } else if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_NONE) - return; - - /* Allocate a Client for this surface */ - c = xdg_surface->data = ecalloc(1, sizeof(*c)); - c->surface.xdg = xdg_surface; - c->bw = borderpx; - - wlr_xdg_toplevel_set_wm_capabilities(xdg_surface->toplevel, - WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); - - LISTEN(&xdg_surface->surface->events.commit, &c->commit, commitnotify); - LISTEN(&xdg_surface->surface->events.map, &c->map, mapnotify); - LISTEN(&xdg_surface->surface->events.unmap, &c->unmap, unmapnotify); - LISTEN(&xdg_surface->events.destroy, &c->destroy, destroynotify); - LISTEN(&xdg_surface->toplevel->events.set_title, &c->set_title, updatetitle); - LISTEN(&xdg_surface->toplevel->events.request_fullscreen, &c->fullscreen, - fullscreennotify); - LISTEN(&xdg_surface->toplevel->events.request_maximize, &c->maximize, - maximizenotify); - LISTEN(&xdg_surface->toplevel->events.request_minimize, &c->minimize, - minimizenotify); + // 标记动画开始 + c->animation.running = true; + c->animation.should_animate = false; + } + // 请求刷新屏幕 + wlr_output_schedule_frame(c->mon->wlr_output); } void // 0.5 -createpointer(struct wlr_pointer *pointer) -{ - struct libinput_device *device; - if (wlr_input_device_is_libinput(&pointer->base) - && (device = wlr_libinput_get_device_handle(&pointer->base))) { - - if (libinput_device_config_tap_get_finger_count(device)) { - libinput_device_config_tap_set_enabled(device, tap_to_click); - libinput_device_config_tap_set_drag_enabled(device, tap_and_drag); - libinput_device_config_tap_set_drag_lock_enabled(device, drag_lock); - libinput_device_config_tap_set_button_map(device, button_map); - } - - if (libinput_device_config_scroll_has_natural_scroll(device)) - libinput_device_config_scroll_set_natural_scroll_enabled(device, natural_scrolling); - - if (libinput_device_config_dwt_is_available(device)) - libinput_device_config_dwt_set_enabled(device, disable_while_typing); - - if (libinput_device_config_left_handed_is_available(device)) - libinput_device_config_left_handed_set(device, left_handed); - - if (libinput_device_config_middle_emulation_is_available(device)) - libinput_device_config_middle_emulation_set_enabled(device, middle_button_emulation); - - if (libinput_device_config_scroll_get_methods(device) != LIBINPUT_CONFIG_SCROLL_NO_SCROLL) - libinput_device_config_scroll_set_method (device, scroll_method); - - if (libinput_device_config_click_get_methods(device) != LIBINPUT_CONFIG_CLICK_METHOD_NONE) - libinput_device_config_click_set_method (device, click_method); - - if (libinput_device_config_send_events_get_modes(device)) - libinput_device_config_send_events_set_mode(device, send_events_mode); - - if (libinput_device_config_accel_is_available(device)) { - libinput_device_config_accel_set_profile(device, accel_profile); - libinput_device_config_accel_set_speed(device, accel_speed); - } - } - - wlr_cursor_attach_input_device(cursor, &pointer->base); +commitnotify(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, commit); + // don't know need to do what... + return; } void // 0.5 -createpointerconstraint(struct wl_listener *listener, void *data) -{ - PointerConstraint *pointer_constraint = ecalloc(1, sizeof(*pointer_constraint)); - pointer_constraint->constraint = data; - LISTEN(&pointer_constraint->constraint->events.destroy, - &pointer_constraint->destroy, destroypointerconstraint); +destroydecoration(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, destroy_decoration); + + wl_list_remove(&c->destroy_decoration.link); + wl_list_remove(&c->set_decoration_mode.link); + motionnotify(0, NULL, 0, 0, 0, 0); } void // 0.5 -cursorconstrain(struct wlr_pointer_constraint_v1 *constraint) -{ - if (active_constraint == constraint) - return; +createdecoration(struct wl_listener *listener, void *data) { + struct wlr_xdg_toplevel_decoration_v1 *deco = data; + Client *c = deco->toplevel->base->data; + c->decoration = deco; - if (active_constraint) - wlr_pointer_constraint_v1_send_deactivated(active_constraint); + LISTEN(&deco->events.request_mode, &c->set_decoration_mode, + requestdecorationmode); + LISTEN(&deco->events.destroy, &c->destroy_decoration, destroydecoration); - active_constraint = constraint; - wlr_pointer_constraint_v1_send_activated(constraint); -} - - -void //0.5 -cursorframe(struct wl_listener *listener, void *data) -{ - /* This event is forwarded by the cursor when a pointer emits an frame - * event. Frame events are sent after regular pointer events to group - * multiple events together. For instance, two axis events may happen at the - * same time, in which case a frame event won't be sent in between. */ - /* Notify the client with pointer focus of the frame event. */ - wlr_seat_pointer_notify_frame(seat); + requestdecorationmode(&c->set_decoration_mode, deco); } void // 0.5 -cursorwarptohint(void) -{ - Client *c = NULL; - double sx = active_constraint->current.cursor_hint.x; - double sy = active_constraint->current.cursor_hint.y; +createidleinhibitor(struct wl_listener *listener, void *data) { + struct wlr_idle_inhibitor_v1 *idle_inhibitor = data; + LISTEN_STATIC(&idle_inhibitor->events.destroy, destroyidleinhibitor); - toplevel_from_wlr_surface(active_constraint->surface, &c, NULL); - /* TODO: wlroots 0.18: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4478 */ - if (c && (active_constraint->current.committed & WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT )) { - wlr_cursor_warp(cursor, NULL, sx + c->geom.x + c->bw, sy + c->geom.y + c->bw); - wlr_seat_pointer_warp(active_constraint->seat, sx, sy); - } + checkidleinhibitor(NULL); } -void -defaultgaps(const Arg *arg) -{ - setgaps(gappoh, gappov, gappih, gappiv); +void // 17 +createkeyboard(struct wlr_keyboard *keyboard) { + struct xkb_context *context; + struct xkb_keymap *keymap; + Keyboard *kb = keyboard->data = ecalloc(1, sizeof(*kb)); + kb->wlr_keyboard = keyboard; + + /* Prepare an XKB keymap and assign it to the keyboard. */ + context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + keymap = xkb_keymap_new_from_names(context, &xkb_rules, + XKB_KEYMAP_COMPILE_NO_FLAGS); + + wlr_keyboard_set_keymap(keyboard, keymap); + xkb_keymap_unref(keymap); + xkb_context_unref(context); + wlr_keyboard_set_repeat_info(keyboard, repeat_rate, repeat_delay); + + if (numlockon == 1) { + uint32_t leds = 0; + xkb_mod_mask_t locked_mods = 0; + leds = leds | WLR_LED_NUM_LOCK; + // 获取numlock所在的位置 + xkb_mod_index_t mod_index = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_NUM); + if (mod_index != XKB_MOD_INVALID) { + locked_mods |= (uint32_t)1 + << mod_index; // 将该位置设置为1,默认为0表示锁住小键盘 + } + // 设置numlock为on + xkb_state_update_mask(keyboard->xkb_state, 0, 0, locked_mods, 0, 0, 0); + wlr_keyboard_led_update(keyboard, leds); // 将表示numlockon的灯打开 + } + + /* Here we set up listeners for keyboard events. */ + LISTEN(&keyboard->events.modifiers, &kb->modifiers, keypressmod); + LISTEN(&keyboard->events.key, &kb->key, keypress); + LISTEN(&keyboard->base.events.destroy, &kb->destroy, cleanupkeyboard); + + wlr_seat_set_keyboard(seat, keyboard); + + kb->key_repeat_source = + wl_event_loop_add_timer(wl_display_get_event_loop(dpy), keyrepeat, kb); + + /* And add the keyboard to our list of keyboards */ + wl_list_insert(&keyboards, &kb->link); } +void // 0.5 +createlayersurface(struct wl_listener *listener, void *data) { + struct wlr_layer_surface_v1 *layer_surface = data; + LayerSurface *l; + struct wlr_surface *surface = layer_surface->surface; + struct wlr_scene_tree *scene_layer = + layers[layermap[layer_surface->pending.layer]]; + struct wlr_layer_surface_v1_state old_state; + if (!layer_surface->output && + !(layer_surface->output = selmon ? selmon->wlr_output : NULL)) { + wlr_layer_surface_v1_destroy(layer_surface); + return; + } -void //0.5 -destroydragicon(struct wl_listener *listener, void *data) -{ - /* Focus enter isn't sent during drag, so refocus the focused node. */ - focusclient(focustop(selmon), 1); - motionnotify(0, NULL, 0, 0, 0, 0); + l = layer_surface->data = ecalloc(1, sizeof(*l)); + l->type = LayerShell; + LISTEN(&surface->events.commit, &l->surface_commit, commitlayersurfacenotify); + LISTEN(&surface->events.map, &l->map, maplayersurfacenotify); + LISTEN(&surface->events.unmap, &l->unmap, unmaplayersurfacenotify); + LISTEN(&layer_surface->events.destroy, &l->destroy, + destroylayersurfacenotify); + + l->layer_surface = layer_surface; + l->mon = layer_surface->output->data; + l->scene_layer = + wlr_scene_layer_surface_v1_create(scene_layer, layer_surface); + l->scene = l->scene_layer->tree; + l->popups = surface->data = wlr_scene_tree_create( + layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP + ? layers[LyrTop] + : scene_layer); + l->scene->node.data = l->popups->node.data = l; + + wl_list_insert(&l->mon->layers[layer_surface->pending.layer], &l->link); + wlr_surface_send_enter(surface, layer_surface->output); + + /* Temporarily set the layer's current state to pending + * so that we can easily arrange it + */ + old_state = layer_surface->current; + layer_surface->current = layer_surface->pending; + l->mapped = 1; + arrangelayers(l->mon); + layer_surface->current = old_state; } -void //17 -destroyidleinhibitor(struct wl_listener *listener, void *data) -{ - /* `data` is the wlr_surface of the idle inhibitor being destroyed, - * at this point the idle inhibitor is still in the list of the manager */ - checkidleinhibitor(wlr_surface_get_root_surface(data)); +void // 0.5 +createlocksurface(struct wl_listener *listener, void *data) { + SessionLock *lock = wl_container_of(listener, lock, new_surface); + struct wlr_session_lock_surface_v1 *lock_surface = data; + Monitor *m = lock_surface->output->data; + struct wlr_scene_tree *scene_tree = lock_surface->surface->data = + wlr_scene_subsurface_tree_create(lock->scene, lock_surface->surface); + m->lock_surface = lock_surface; + + wlr_scene_node_set_position(&scene_tree->node, m->m.x, m->m.y); + wlr_session_lock_surface_v1_configure(lock_surface, m->m.width, m->m.height); + + LISTEN(&lock_surface->events.destroy, &m->destroy_lock_surface, + destroylocksurface); + + if (m == selmon) + client_notify_enter(lock_surface->surface, wlr_seat_get_keyboard(seat)); } -void //0.5 -destroylayersurfacenotify(struct wl_listener *listener, void *data) -{ - LayerSurface *l = wl_container_of(listener, l, destroy); +void // 17 need fix 0.5 +createmon(struct wl_listener *listener, void *data) { + /* This event is raised by the backend when a new output (aka a display or + * monitor) becomes available. */ + struct wlr_output *wlr_output = data; + const MonitorRule *r; + size_t i; + Monitor *m = wlr_output->data = ecalloc(1, sizeof(*m)); + m->wlr_output = wlr_output; - wl_list_remove(&l->link); - wl_list_remove(&l->destroy.link); - wl_list_remove(&l->map.link); - wl_list_remove(&l->unmap.link); - wl_list_remove(&l->surface_commit.link); - wlr_scene_node_destroy(&l->scene->node); - wlr_scene_node_destroy(&l->popups->node); - free(l); + wl_list_init(&m->dwl_ipc_outputs); + wlr_output_init_render(wlr_output, alloc, drw); + + /* Initialize monitor state using configured rules */ + for (i = 0; i < LENGTH(m->layers); i++) + wl_list_init(&m->layers[i]); + + m->gappih = gappih; + m->gappiv = gappiv; + m->gappoh = gappoh; + m->gappov = gappov; + m->isoverview = 0; + m->sel = NULL; + m->is_in_hotarea = 0; + m->tagset[0] = m->tagset[1] = 1; + float scale = 1; + m->mfact = default_mfact; + m->nmaster = default_nmaster; + enum wl_output_transform rr = WL_OUTPUT_TRANSFORM_NORMAL; + + if (LENGTH(layouts) > 1) { + m->lt[0] = &layouts[0]; // 默认就有两个布局 + m->lt[1] = &layouts[1]; + } else { + m->lt[0] = m->lt[1] = &layouts[0]; + } + for (r = monrules; r < END(monrules); r++) { + if (!r->name || strstr(wlr_output->name, r->name)) { + m->mfact = r->mfact; + m->nmaster = r->nmaster; + m->m.x = r->x; + m->m.y = r->y; + if (r->lt) + m->lt[0] = m->lt[1] = r->lt; + scale = r->scale; + rr = r->rr; + break; + } + } + + wlr_output_set_scale(wlr_output, scale); + wlr_xcursor_manager_load(cursor_mgr, scale); + wlr_output_set_transform(wlr_output, rr); + /* The mode is a tuple of (width, height, refresh rate), and each + * monitor supports only a specific set of modes. We just pick the + * monitor's preferred mode; a more sophisticated compositor would let + * the user configure it. */ + wlr_output_set_mode(wlr_output, wlr_output_preferred_mode(wlr_output)); + + /* Set up event listeners */ + LISTEN(&wlr_output->events.frame, &m->frame, rendermon); + LISTEN(&wlr_output->events.destroy, &m->destroy, cleanupmon); + LISTEN(&wlr_output->events.request_state, &m->request_state, requestmonstate); + + wlr_output_enable(wlr_output, 1); + if (!wlr_output_commit(wlr_output)) + return; + + /* Try to enable adaptive sync, note that not all monitors support it. + * wlr_output_commit() will deactivate it in case it cannot be enabled */ + wlr_output_enable_adaptive_sync(wlr_output, 1); + wlr_output_commit(wlr_output); + + wl_list_insert(&mons, &m->link); + printstatus(); + + m->pertag = calloc(1, sizeof(Pertag)); + m->pertag->curtag = m->pertag->prevtag = 1; + + for (i = 0; i <= LENGTH(tags); i++) { + m->pertag->nmasters[i] = m->nmaster; + m->pertag->mfacts[i] = m->mfact; + + m->pertag->ltidxs[i][0] = m->lt[0]; + m->pertag->ltidxs[i][1] = m->lt[1]; + m->pertag->sellts[i] = m->sellt; + } + + /* The xdg-protocol specifies: + * + * If the fullscreened surface is not opaque, the compositor must make + * sure that other screen content not part of the same surface tree (made + * up of subsurfaces, popups or similarly coupled surfaces) are not + * visible below the fullscreened surface. + * + */ + /* updatemons() will resize and set correct position */ + // m->fullscreen_bg = wlr_scene_rect_create(layers[LyrFS], 0, 0, + // fullscreen_bg); wlr_scene_node_set_enabled(&m->fullscreen_bg->node, 0); + + /* Adds this to the output layout in the order it was configured in. + * + * The output layout utility automatically adds a wl_output global to the + * display, which Wayland clients can see to find out information about the + * output (such as DPI, scale factor, manufacturer, etc). + */ + m->scene_output = wlr_scene_output_create(scene, wlr_output); + if (m->m.x < 0 || m->m.y < 0) + wlr_output_layout_add_auto(output_layout, wlr_output); + else + wlr_output_layout_add(output_layout, wlr_output, m->m.x, m->m.y); + strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol)); } -void //0.5 -destroylock(SessionLock *lock, int unlock) -{ - wlr_seat_keyboard_notify_clear_focus(seat); - if ((locked = !unlock)) - goto destroy; +void // fix for 0.5 +createnotify(struct wl_listener *listener, void *data) { + /* This event is raised when wlr_xdg_shell receives a new xdg surface from a + * client, either a toplevel (application window) or popup, + * or when wlr_layer_shell receives a new popup from a layer. + * If you want to do something tricky with popups you should check if + * its parent is wlr_xdg_shell or wlr_layer_shell */ + struct wlr_xdg_surface *xdg_surface = data; + Client *c = NULL; + LayerSurface *l = NULL; - wlr_scene_node_set_enabled(&locked_bg->node, 0); + if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { + struct wlr_xdg_popup *popup = xdg_surface->popup; + struct wlr_box box; + if (toplevel_from_wlr_surface(popup->base->surface, &c, &l) < 0) + return; + popup->base->surface->data = + wlr_scene_xdg_surface_create(popup->parent->data, popup->base); + if ((l && !l->mon) || (c && !c->mon)) + return; + box = l ? l->mon->m : c->mon->w; + box.x -= (l ? l->geom.x : c->geom.x); + box.y -= (l ? l->geom.y : c->geom.y); + wlr_xdg_popup_unconstrain_from_box(popup, &box); + return; + } else if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_NONE) + return; - focusclient(focustop(selmon), 0); - motionnotify(0, NULL, 0, 0, 0, 0); + /* Allocate a Client for this surface */ + c = xdg_surface->data = ecalloc(1, sizeof(*c)); + c->surface.xdg = xdg_surface; + c->bw = borderpx; + + wlr_xdg_toplevel_set_wm_capabilities( + xdg_surface->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); + + LISTEN(&xdg_surface->surface->events.commit, &c->commit, commitnotify); + LISTEN(&xdg_surface->surface->events.map, &c->map, mapnotify); + LISTEN(&xdg_surface->surface->events.unmap, &c->unmap, unmapnotify); + LISTEN(&xdg_surface->events.destroy, &c->destroy, destroynotify); + LISTEN(&xdg_surface->toplevel->events.set_title, &c->set_title, updatetitle); + LISTEN(&xdg_surface->toplevel->events.request_fullscreen, &c->fullscreen, + fullscreennotify); + LISTEN(&xdg_surface->toplevel->events.request_maximize, &c->maximize, + maximizenotify); + LISTEN(&xdg_surface->toplevel->events.request_minimize, &c->minimize, + minimizenotify); +} + +void // 0.5 +createpointer(struct wlr_pointer *pointer) { + struct libinput_device *device; + if (wlr_input_device_is_libinput(&pointer->base) && + (device = wlr_libinput_get_device_handle(&pointer->base))) { + + if (libinput_device_config_tap_get_finger_count(device)) { + libinput_device_config_tap_set_enabled(device, tap_to_click); + libinput_device_config_tap_set_drag_enabled(device, tap_and_drag); + libinput_device_config_tap_set_drag_lock_enabled(device, drag_lock); + libinput_device_config_tap_set_button_map(device, button_map); + } + + if (libinput_device_config_scroll_has_natural_scroll(device)) + libinput_device_config_scroll_set_natural_scroll_enabled( + device, natural_scrolling); + + if (libinput_device_config_dwt_is_available(device)) + libinput_device_config_dwt_set_enabled(device, disable_while_typing); + + if (libinput_device_config_left_handed_is_available(device)) + libinput_device_config_left_handed_set(device, left_handed); + + if (libinput_device_config_middle_emulation_is_available(device)) + libinput_device_config_middle_emulation_set_enabled( + device, middle_button_emulation); + + if (libinput_device_config_scroll_get_methods(device) != + LIBINPUT_CONFIG_SCROLL_NO_SCROLL) + libinput_device_config_scroll_set_method(device, scroll_method); + + if (libinput_device_config_click_get_methods(device) != + LIBINPUT_CONFIG_CLICK_METHOD_NONE) + libinput_device_config_click_set_method(device, click_method); + + if (libinput_device_config_send_events_get_modes(device)) + libinput_device_config_send_events_set_mode(device, send_events_mode); + + if (libinput_device_config_accel_is_available(device)) { + libinput_device_config_accel_set_profile(device, accel_profile); + libinput_device_config_accel_set_speed(device, accel_speed); + } + } + + wlr_cursor_attach_input_device(cursor, &pointer->base); +} + +void // 0.5 +createpointerconstraint(struct wl_listener *listener, void *data) { + PointerConstraint *pointer_constraint = + ecalloc(1, sizeof(*pointer_constraint)); + pointer_constraint->constraint = data; + LISTEN(&pointer_constraint->constraint->events.destroy, + &pointer_constraint->destroy, destroypointerconstraint); +} + +void // 0.5 +cursorconstrain(struct wlr_pointer_constraint_v1 *constraint) { + if (active_constraint == constraint) + return; + + if (active_constraint) + wlr_pointer_constraint_v1_send_deactivated(active_constraint); + + active_constraint = constraint; + wlr_pointer_constraint_v1_send_activated(constraint); +} + +void // 0.5 +cursorframe(struct wl_listener *listener, void *data) { + /* This event is forwarded by the cursor when a pointer emits an frame + * event. Frame events are sent after regular pointer events to group + * multiple events together. For instance, two axis events may happen at the + * same time, in which case a frame event won't be sent in between. */ + /* Notify the client with pointer focus of the frame event. */ + wlr_seat_pointer_notify_frame(seat); +} + +void // 0.5 +cursorwarptohint(void) { + Client *c = NULL; + double sx = active_constraint->current.cursor_hint.x; + double sy = active_constraint->current.cursor_hint.y; + + toplevel_from_wlr_surface(active_constraint->surface, &c, NULL); + /* TODO: wlroots 0.18: + * https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4478 */ + if (c && (active_constraint->current.committed & + WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT)) { + wlr_cursor_warp(cursor, NULL, sx + c->geom.x + c->bw, + sy + c->geom.y + c->bw); + wlr_seat_pointer_warp(active_constraint->seat, sx, sy); + } +} + +void defaultgaps(const Arg *arg) { setgaps(gappoh, gappov, gappih, gappiv); } + +void // 0.5 +destroydragicon(struct wl_listener *listener, void *data) { + /* Focus enter isn't sent during drag, so refocus the focused node. */ + focusclient(focustop(selmon), 1); + motionnotify(0, NULL, 0, 0, 0, 0); +} + +void // 17 +destroyidleinhibitor(struct wl_listener *listener, void *data) { + /* `data` is the wlr_surface of the idle inhibitor being destroyed, + * at this point the idle inhibitor is still in the list of the manager */ + checkidleinhibitor(wlr_surface_get_root_surface(data)); +} + +void // 0.5 +destroylayersurfacenotify(struct wl_listener *listener, void *data) { + LayerSurface *l = wl_container_of(listener, l, destroy); + + wl_list_remove(&l->link); + wl_list_remove(&l->destroy.link); + wl_list_remove(&l->map.link); + wl_list_remove(&l->unmap.link); + wl_list_remove(&l->surface_commit.link); + wlr_scene_node_destroy(&l->scene->node); + wlr_scene_node_destroy(&l->popups->node); + free(l); +} + +void // 0.5 +destroylock(SessionLock *lock, int unlock) { + wlr_seat_keyboard_notify_clear_focus(seat); + if ((locked = !unlock)) + goto destroy; + + wlr_scene_node_set_enabled(&locked_bg->node, 0); + + focusclient(focustop(selmon), 0); + motionnotify(0, NULL, 0, 0, 0, 0); destroy: - wl_list_remove(&lock->new_surface.link); - wl_list_remove(&lock->unlock.link); - wl_list_remove(&lock->destroy.link); + wl_list_remove(&lock->new_surface.link); + wl_list_remove(&lock->unlock.link); + wl_list_remove(&lock->destroy.link); - wlr_scene_node_destroy(&lock->scene->node); - cur_lock = NULL; - free(lock); -} - -void //0.5 -destroylocksurface(struct wl_listener *listener, void *data) -{ - Monitor *m = wl_container_of(listener, m, destroy_lock_surface); - struct wlr_session_lock_surface_v1 *surface, *lock_surface = m->lock_surface; - - m->lock_surface = NULL; - wl_list_remove(&m->destroy_lock_surface.link); - - if (lock_surface->surface != seat->keyboard_state.focused_surface) - return; - - if (locked && cur_lock && !wl_list_empty(&cur_lock->surfaces)) { - surface = wl_container_of(cur_lock->surfaces.next, surface, link); - client_notify_enter(surface->surface, wlr_seat_get_keyboard(seat)); - } else if (!locked) { - focusclient(focustop(selmon), 1); - } else { - wlr_seat_keyboard_clear_focus(seat); - } -} - - -void //0.5 -destroynotify(struct wl_listener *listener, void *data) -{ - /* Called when the xdg_toplevel is destroyed. */ - Client *c = wl_container_of(listener, c, destroy); - wl_list_remove(&c->destroy.link); - wl_list_remove(&c->set_title.link); - wl_list_remove(&c->fullscreen.link); - wl_list_remove(&c->maximize.link); - wl_list_remove(&c->minimize.link); -#ifdef XWAYLAND - if (c->type != XDGShell) { - wl_list_remove(&c->activate.link); - wl_list_remove(&c->associate.link); - wl_list_remove(&c->configure.link); - wl_list_remove(&c->dissociate.link); - wl_list_remove(&c->set_hints.link); - } else -#endif - { - wl_list_remove(&c->commit.link); - wl_list_remove(&c->map.link); - wl_list_remove(&c->unmap.link); - } - free(c); + wlr_scene_node_destroy(&lock->scene->node); + cur_lock = NULL; + free(lock); } void // 0.5 -destroypointerconstraint(struct wl_listener *listener, void *data) -{ - PointerConstraint *pointer_constraint = wl_container_of(listener, pointer_constraint, destroy); +destroylocksurface(struct wl_listener *listener, void *data) { + Monitor *m = wl_container_of(listener, m, destroy_lock_surface); + struct wlr_session_lock_surface_v1 *surface, *lock_surface = m->lock_surface; - if (active_constraint == pointer_constraint->constraint) { - cursorwarptohint(); - active_constraint = NULL; - } + m->lock_surface = NULL; + wl_list_remove(&m->destroy_lock_surface.link); - wl_list_remove(&pointer_constraint->destroy.link); - free(pointer_constraint); + if (lock_surface->surface != seat->keyboard_state.focused_surface) + return; + + if (locked && cur_lock && !wl_list_empty(&cur_lock->surfaces)) { + surface = wl_container_of(cur_lock->surfaces.next, surface, link); + client_notify_enter(surface->surface, wlr_seat_get_keyboard(seat)); + } else if (!locked) { + focusclient(focustop(selmon), 1); + } else { + wlr_seat_keyboard_clear_focus(seat); + } } -void //0.5 -destroysessionlock(struct wl_listener *listener, void *data) -{ - SessionLock *lock = wl_container_of(listener, lock, destroy); - destroylock(lock, 0); - motionnotify(0, NULL, 0, 0, 0, 0); +void // 0.5 +destroynotify(struct wl_listener *listener, void *data) { + /* Called when the xdg_toplevel is destroyed. */ + Client *c = wl_container_of(listener, c, destroy); + wl_list_remove(&c->destroy.link); + wl_list_remove(&c->set_title.link); + wl_list_remove(&c->fullscreen.link); + wl_list_remove(&c->maximize.link); + wl_list_remove(&c->minimize.link); +#ifdef XWAYLAND + if (c->type != XDGShell) { + wl_list_remove(&c->activate.link); + wl_list_remove(&c->associate.link); + wl_list_remove(&c->configure.link); + wl_list_remove(&c->dissociate.link); + wl_list_remove(&c->set_hints.link); + } else +#endif + { + wl_list_remove(&c->commit.link); + wl_list_remove(&c->map.link); + wl_list_remove(&c->unmap.link); + } + free(c); } +void // 0.5 +destroypointerconstraint(struct wl_listener *listener, void *data) { + PointerConstraint *pointer_constraint = + wl_container_of(listener, pointer_constraint, destroy); -void //0.5 -destroysessionmgr(struct wl_listener *listener, void *data) -{ - wl_list_remove(&lock_listener.link); - wl_list_remove(&listener->link); + if (active_constraint == pointer_constraint->constraint) { + cursorwarptohint(); + active_constraint = NULL; + } + + wl_list_remove(&pointer_constraint->destroy.link); + free(pointer_constraint); } -void //17 -associatex11(struct wl_listener *listener, void *data) -{ - Client *c = wl_container_of(listener, c, associate); - - LISTEN(&client_surface(c)->events.map, &c->map, mapnotify); - LISTEN(&client_surface(c)->events.unmap, &c->unmap, unmapnotify); +void // 0.5 +destroysessionlock(struct wl_listener *listener, void *data) { + SessionLock *lock = wl_container_of(listener, lock, destroy); + destroylock(lock, 0); + motionnotify(0, NULL, 0, 0, 0, 0); } -void //17 -dissociatex11(struct wl_listener *listener, void *data) -{ - Client *c = wl_container_of(listener, c, dissociate); - wl_list_remove(&c->map.link); - wl_list_remove(&c->unmap.link); +void // 0.5 +destroysessionmgr(struct wl_listener *listener, void *data) { + wl_list_remove(&lock_listener.link); + wl_list_remove(&listener->link); } +void // 17 +associatex11(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, associate); -Monitor * //0.5 -dirtomon(enum wlr_direction dir) -{ - struct wlr_output *next; - if (!wlr_output_layout_get(output_layout, selmon->wlr_output)) - return selmon; - if ((next = wlr_output_layout_adjacent_output(output_layout, - dir, selmon->wlr_output, selmon->m.x, selmon->m.y))) - return next->data; - if ((next = wlr_output_layout_farthest_output(output_layout, - dir ^ (WLR_DIRECTION_LEFT|WLR_DIRECTION_RIGHT), - selmon->wlr_output, selmon->m.x, selmon->m.y))) - return next->data; - return selmon; + LISTEN(&client_surface(c)->events.map, &c->map, mapnotify); + LISTEN(&client_surface(c)->events.unmap, &c->unmap, unmapnotify); } +void // 17 +dissociatex11(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, dissociate); + wl_list_remove(&c->map.link); + wl_list_remove(&c->unmap.link); +} +Monitor * // 0.5 +dirtomon(enum wlr_direction dir) { + struct wlr_output *next; + if (!wlr_output_layout_get(output_layout, selmon->wlr_output)) + return selmon; + if ((next = wlr_output_layout_adjacent_output( + output_layout, dir, selmon->wlr_output, selmon->m.x, selmon->m.y))) + return next->data; + if ((next = wlr_output_layout_farthest_output( + output_layout, dir ^ (WLR_DIRECTION_LEFT | WLR_DIRECTION_RIGHT), + selmon->wlr_output, selmon->m.x, selmon->m.y))) + return next->data; + return selmon; +} -void dwl_ipc_manager_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) { - struct wl_resource *manager_resource = wl_resource_create(client, &zdwl_ipc_manager_v2_interface, version, id); - if (!manager_resource) { - wl_client_post_no_memory(client); - return; - } - wl_resource_set_implementation(manager_resource, &dwl_manager_implementation, NULL, dwl_ipc_manager_destroy); +void dwl_ipc_manager_bind(struct wl_client *client, void *data, + uint32_t version, uint32_t id) { + struct wl_resource *manager_resource = + wl_resource_create(client, &zdwl_ipc_manager_v2_interface, version, id); + if (!manager_resource) { + wl_client_post_no_memory(client); + return; + } + wl_resource_set_implementation(manager_resource, &dwl_manager_implementation, + NULL, dwl_ipc_manager_destroy); - zdwl_ipc_manager_v2_send_tags(manager_resource, LENGTH(tags)); + zdwl_ipc_manager_v2_send_tags(manager_resource, LENGTH(tags)); - for (int i = 0; i < LENGTH(layouts); i++) - zdwl_ipc_manager_v2_send_layout(manager_resource, layouts[i].symbol); + for (int i = 0; i < LENGTH(layouts); i++) + zdwl_ipc_manager_v2_send_layout(manager_resource, layouts[i].symbol); } void dwl_ipc_manager_destroy(struct wl_resource *resource) { - /* No state to destroy */ + /* No state to destroy */ } -void dwl_ipc_manager_get_output(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *output) { - DwlIpcOutput *ipc_output; - Monitor *monitor = wlr_output_from_resource(output)->data; - struct wl_resource *output_resource = wl_resource_create(client, &zdwl_ipc_output_v2_interface, wl_resource_get_version(resource), id); - if (!output_resource) - return; +void dwl_ipc_manager_get_output(struct wl_client *client, + struct wl_resource *resource, uint32_t id, + struct wl_resource *output) { + DwlIpcOutput *ipc_output; + Monitor *monitor = wlr_output_from_resource(output)->data; + struct wl_resource *output_resource = + wl_resource_create(client, &zdwl_ipc_output_v2_interface, + wl_resource_get_version(resource), id); + if (!output_resource) + return; - ipc_output = ecalloc(1, sizeof(*ipc_output)); - ipc_output->resource = output_resource; - ipc_output->monitor = monitor; - wl_resource_set_implementation(output_resource, &dwl_output_implementation, ipc_output, dwl_ipc_output_destroy); - wl_list_insert(&monitor->dwl_ipc_outputs, &ipc_output->link); - dwl_ipc_output_printstatus_to(ipc_output); + ipc_output = ecalloc(1, sizeof(*ipc_output)); + ipc_output->resource = output_resource; + ipc_output->monitor = monitor; + wl_resource_set_implementation(output_resource, &dwl_output_implementation, + ipc_output, dwl_ipc_output_destroy); + wl_list_insert(&monitor->dwl_ipc_outputs, &ipc_output->link); + dwl_ipc_output_printstatus_to(ipc_output); } -void dwl_ipc_manager_release(struct wl_client *client, struct wl_resource *resource) { - wl_resource_destroy(resource); +void dwl_ipc_manager_release(struct wl_client *client, + struct wl_resource *resource) { + wl_resource_destroy(resource); } // 在外部ipc客户端结束的时候会发出销毁请求,比如kill掉waybar,就会销毁waybar绑定的ipc_output static void dwl_ipc_output_destroy(struct wl_resource *resource) { - DwlIpcOutput *ipc_output = wl_resource_get_user_data(resource); - wl_list_remove(&ipc_output->link); - free(ipc_output); + DwlIpcOutput *ipc_output = wl_resource_get_user_data(resource); + wl_list_remove(&ipc_output->link); + free(ipc_output); } void dwl_ipc_output_printstatus(Monitor *monitor) { - DwlIpcOutput *ipc_output; - wl_list_for_each(ipc_output, &monitor->dwl_ipc_outputs, link) - dwl_ipc_output_printstatus_to(ipc_output); + DwlIpcOutput *ipc_output; + wl_list_for_each(ipc_output, &monitor->dwl_ipc_outputs, link) + dwl_ipc_output_printstatus_to(ipc_output); } void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output) { - Monitor *monitor = ipc_output->monitor; - Client *c, *focused; - int tagmask, state, numclients, focused_client, tag; - const char *title, *appid,*symbol; - focused = focustop(monitor); - zdwl_ipc_output_v2_send_active(ipc_output->resource, monitor == selmon); + Monitor *monitor = ipc_output->monitor; + Client *c, *focused; + int tagmask, state, numclients, focused_client, tag; + const char *title, *appid, *symbol; + focused = focustop(monitor); + zdwl_ipc_output_v2_send_active(ipc_output->resource, monitor == selmon); - if ((monitor->tagset[monitor->seltags] & TAGMASK) == TAGMASK) { - state = 0; - state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE; - zdwl_ipc_output_v2_send_tag(ipc_output->resource, 888, state, 1, 1); - } else { - for ( tag = 0 ; tag < LENGTH(tags); tag++) { - numclients = state = focused_client = 0; - tagmask = 1 << tag; - if ((tagmask & monitor->tagset[monitor->seltags]) != 0) - state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE; + if ((monitor->tagset[monitor->seltags] & TAGMASK) == TAGMASK) { + state = 0; + state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE; + zdwl_ipc_output_v2_send_tag(ipc_output->resource, 888, state, 1, 1); + } else { + for (tag = 0; tag < LENGTH(tags); tag++) { + numclients = state = focused_client = 0; + tagmask = 1 << tag; + if ((tagmask & monitor->tagset[monitor->seltags]) != 0) + state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE; - wl_list_for_each(c, &clients, link) { - if (c->mon != monitor) - continue; - if (!(c->tags & tagmask)) - continue; - if (c == focused) - focused_client = 1; - if (c->isurgent) - state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT; + wl_list_for_each(c, &clients, link) { + if (c->mon != monitor) + continue; + if (!(c->tags & tagmask)) + continue; + if (c == focused) + focused_client = 1; + if (c->isurgent) + state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT; - numclients++; - } - zdwl_ipc_output_v2_send_tag(ipc_output->resource, tag, state, numclients, focused_client); - } - } + numclients++; + } + zdwl_ipc_output_v2_send_tag(ipc_output->resource, tag, state, numclients, + focused_client); + } + } - // for ( tag = 0 ; tag < LENGTH(tags); tag++) { - // numclients = state = focused_client = 0; - // tagmask = 1 << tag; - // if ((tagmask & monitor->tagset[monitor->seltags]) != 0) - // state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE; - // wl_list_for_each(c, &clients, link) { - // if (c->mon != monitor) - // continue; - // if (!(c->tags & tagmask)) - // continue; - // if (c == focused) - // focused_client = 1; - // if (c->isurgent) - // state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT; - // numclients++; - // } - // zdwl_ipc_output_v2_send_tag(ipc_output->resource, tag, state, numclients, focused_client); - // } + // for ( tag = 0 ; tag < LENGTH(tags); tag++) { + // numclients = state = focused_client = 0; + // tagmask = 1 << tag; + // if ((tagmask & monitor->tagset[monitor->seltags]) != 0) + // state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE; + // wl_list_for_each(c, &clients, link) { + // if (c->mon != monitor) + // continue; + // if (!(c->tags & tagmask)) + // continue; + // if (c == focused) + // focused_client = 1; + // if (c->isurgent) + // state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT; + // numclients++; + // } + // zdwl_ipc_output_v2_send_tag(ipc_output->resource, tag, state, + // numclients, focused_client); + // } - title = focused ? client_get_title(focused) : ""; - appid = focused ? client_get_appid(focused) : ""; - symbol = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]->symbol; + title = focused ? client_get_title(focused) : ""; + appid = focused ? client_get_appid(focused) : ""; + symbol = + selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]->symbol; - zdwl_ipc_output_v2_send_layout(ipc_output->resource, monitor->lt[monitor->sellt] - layouts); - zdwl_ipc_output_v2_send_title(ipc_output->resource, title ? title : broken); - zdwl_ipc_output_v2_send_appid(ipc_output->resource, appid ? appid : broken); - zdwl_ipc_output_v2_send_layout_symbol(ipc_output->resource, symbol); - zdwl_ipc_output_v2_send_frame(ipc_output->resource); + zdwl_ipc_output_v2_send_layout(ipc_output->resource, + monitor->lt[monitor->sellt] - layouts); + zdwl_ipc_output_v2_send_title(ipc_output->resource, title ? title : broken); + zdwl_ipc_output_v2_send_appid(ipc_output->resource, appid ? appid : broken); + zdwl_ipc_output_v2_send_layout_symbol(ipc_output->resource, symbol); + zdwl_ipc_output_v2_send_frame(ipc_output->resource); } -void dwl_ipc_output_set_client_tags(struct wl_client *client, struct wl_resource *resource, uint32_t and_tags, uint32_t xor_tags) { - DwlIpcOutput *ipc_output; - Monitor *monitor; - Client *selected_client; - unsigned int newtags = 0; +void dwl_ipc_output_set_client_tags(struct wl_client *client, + struct wl_resource *resource, + uint32_t and_tags, uint32_t xor_tags) { + DwlIpcOutput *ipc_output; + Monitor *monitor; + Client *selected_client; + unsigned int newtags = 0; - ipc_output = wl_resource_get_user_data(resource); - if (!ipc_output) - return; + ipc_output = wl_resource_get_user_data(resource); + if (!ipc_output) + return; - monitor = ipc_output->monitor; - selected_client = focustop(monitor); - if (!selected_client) - return; + monitor = ipc_output->monitor; + selected_client = focustop(monitor); + if (!selected_client) + return; - newtags = (selected_client->tags & and_tags) ^ xor_tags; - if (!newtags) - return; + newtags = (selected_client->tags & and_tags) ^ xor_tags; + if (!newtags) + return; - selected_client->tags = newtags; - focusclient(focustop(selmon), 1); - arrange(selmon,true); - printstatus(); + selected_client->tags = newtags; + focusclient(focustop(selmon), 1); + arrange(selmon, true); + printstatus(); } -void dwl_ipc_output_set_layout(struct wl_client *client, struct wl_resource *resource, uint32_t index) { - DwlIpcOutput *ipc_output; - Monitor *monitor; +void dwl_ipc_output_set_layout(struct wl_client *client, + struct wl_resource *resource, uint32_t index) { + DwlIpcOutput *ipc_output; + Monitor *monitor; - ipc_output = wl_resource_get_user_data(resource); - if (!ipc_output) - return; + ipc_output = wl_resource_get_user_data(resource); + if (!ipc_output) + return; - monitor = ipc_output->monitor; - if (index >= LENGTH(layouts)) - return; - if (index != monitor->lt[monitor->sellt] - layouts) - monitor->sellt ^= 1; + monitor = ipc_output->monitor; + if (index >= LENGTH(layouts)) + return; + if (index != monitor->lt[monitor->sellt] - layouts) + monitor->sellt ^= 1; - monitor->lt[monitor->sellt] = &layouts[index]; - arrange(monitor,false); - printstatus(); + monitor->lt[monitor->sellt] = &layouts[index]; + arrange(monitor, false); + printstatus(); } -void dwl_ipc_output_set_tags(struct wl_client *client, struct wl_resource *resource, uint32_t tagmask, uint32_t toggle_tagset) { - DwlIpcOutput *ipc_output; - Monitor *monitor; - unsigned int newtags = tagmask & TAGMASK; +void dwl_ipc_output_set_tags(struct wl_client *client, + struct wl_resource *resource, uint32_t tagmask, + uint32_t toggle_tagset) { + DwlIpcOutput *ipc_output; + Monitor *monitor; + unsigned int newtags = tagmask & TAGMASK; - ipc_output = wl_resource_get_user_data(resource); - if (!ipc_output) - return; - monitor = ipc_output->monitor; + ipc_output = wl_resource_get_user_data(resource); + if (!ipc_output) + return; + monitor = ipc_output->monitor; - if (!newtags || newtags == monitor->tagset[monitor->seltags]) - return; - if (toggle_tagset) - monitor->seltags ^= 1; + if (!newtags || newtags == monitor->tagset[monitor->seltags]) + return; + if (toggle_tagset) + monitor->seltags ^= 1; - monitor->tagset[monitor->seltags] = newtags; - focusclient(focustop(monitor), 1); - arrange(monitor,true); - printstatus(); + monitor->tagset[monitor->seltags] = newtags; + focusclient(focustop(monitor), 1); + arrange(monitor, true); + printstatus(); } -void dwl_ipc_output_release(struct wl_client *client, struct wl_resource *resource) { - wl_resource_destroy(resource); +void dwl_ipc_output_release(struct wl_client *client, + struct wl_resource *resource) { + wl_resource_destroy(resource); } +void focusclient(Client *c, int lift) { + struct wlr_surface *old = seat->keyboard_state.focused_surface; + if (locked) + return; -void -focusclient(Client *c, int lift) -{ - struct wlr_surface *old = seat->keyboard_state.focused_surface; - if (locked) - return; + if (c && c->iskilling) + return; - if (c && c->iskilling) - return; + /* Raise client in stacking order if requested */ + if (c && lift) + wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层 - /* Raise client in stacking order if requested */ - if (c && lift) - wlr_scene_node_raise_to_top(&c->scene->node); //将视图提升到顶层 + if (c && client_surface(c) == old) + return; - if (c && client_surface(c) == old) - return; + if (c && c->mon && c->mon != selmon) { + selmon = c->mon; + } - if (c && c->mon && c->mon != selmon) { - selmon = c->mon; - } + if (selmon && selmon->sel && selmon->sel->foreign_toplevel) { + wlr_foreign_toplevel_handle_v1_set_activated(selmon->sel->foreign_toplevel, + false); + } + if (selmon) + selmon->sel = c; + if (c && c->foreign_toplevel) + wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); - if(selmon && selmon->sel && selmon->sel->foreign_toplevel) { - wlr_foreign_toplevel_handle_v1_set_activated(selmon->sel->foreign_toplevel,false); - } - if(selmon) - selmon->sel = c; - if(c && c->foreign_toplevel) - wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel,true); + /* Put the new client atop the focus stack and select its monitor */ + if (c && !client_is_unmanaged(c)) { + wl_list_remove(&c->flink); + wl_list_insert(&fstack, &c->flink); + selmon = c->mon; + c->isurgent = 0; + client_restack_surface(c); + setborder_color(c); + /* Don't change border color if there is an exclusive focus or we are + * handling a drag operation */ + } - /* Put the new client atop the focus stack and select its monitor */ - if (c && !client_is_unmanaged(c)) { - wl_list_remove(&c->flink); - wl_list_insert(&fstack, &c->flink); - selmon = c->mon; - c->isurgent = 0; - client_restack_surface(c); - setborder_color(c); - /* Don't change border color if there is an exclusive focus or we are - * handling a drag operation */ - } + /* Deactivate old client if focus is changing */ + if (old && (!c || client_surface(c) != old)) { + /* If an overlay is focused, don't focus or activate the client, + * but only update its position in fstack to render its border with + * focuscolor and focus it after the overlay is closed. */ + Client *w = NULL; + LayerSurface *l = NULL; + int type = toplevel_from_wlr_surface(old, &w, &l); + if (type == LayerShell && l->scene->node.enabled && + l->layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) { + return; + } else if (w && w == exclusive_focus && client_wants_focus(w)) { + return; + /* Don't deactivate old client if the new one wants focus, as this causes + * issues with winecfg and probably other clients */ + } else if (w && !client_is_unmanaged(w) && (!c || !client_wants_focus(c))) { + setborder_color(w); - /* Deactivate old client if focus is changing */ - if (old && (!c || client_surface(c) != old)) { - /* If an overlay is focused, don't focus or activate the client, - * but only update its position in fstack to render its border with focuscolor - * and focus it after the overlay is closed. */ - Client *w = NULL; - LayerSurface *l = NULL; - int type = toplevel_from_wlr_surface(old, &w, &l); - if (type == LayerShell && l->scene->node.enabled - && l->layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) { - return; - } else if (w && w == exclusive_focus && client_wants_focus(w)) { - return; - /* Don't deactivate old client if the new one wants focus, as this causes issues with winecfg - * and probably other clients */ - } else if (w && !client_is_unmanaged(w) && (!c || !client_wants_focus(c))) { - setborder_color(w); + client_activate_surface(old, 0); + } + } + printstatus(); - client_activate_surface(old, 0); - } - } - printstatus(); + if (!c) { + /* With no client, all we have left is to clear focus */ + if (selmon && selmon->sel) + selmon->sel = + NULL; // 这个很关键,因为很多地方用到当前窗口做计算,不重置成NULL就会到处有野指针 +#ifdef IM + dwl_input_method_relay_set_focus(input_relay, NULL); +#endif + wlr_seat_keyboard_notify_clear_focus(seat); + return; + } - if (!c) { - /* With no client, all we have left is to clear focus */ - if(selmon && selmon->sel) - selmon->sel = NULL; //这个很关键,因为很多地方用到当前窗口做计算,不重置成NULL就会到处有野指针 - #ifdef IM - dwl_input_method_relay_set_focus(input_relay, NULL); - #endif - wlr_seat_keyboard_notify_clear_focus(seat); - return; - } + /* Change cursor surface */ + motionnotify(0, NULL, 0, 0, 0, 0); - /* Change cursor surface */ - motionnotify(0, NULL, 0, 0, 0, 0); - - /* Have a client, so focus its top-level wlr_surface */ - client_notify_enter(client_surface(c), wlr_seat_get_keyboard(seat)); + /* Have a client, so focus its top-level wlr_surface */ + client_notify_enter(client_surface(c), wlr_seat_get_keyboard(seat)); #ifdef IM - struct wlr_keyboard *keyboard; - keyboard = wlr_seat_get_keyboard(seat); - uint32_t mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; - if (mods == 0) - dwl_input_method_relay_set_focus(input_relay, client_surface(c)); + struct wlr_keyboard *keyboard; + keyboard = wlr_seat_get_keyboard(seat); + uint32_t mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; + if (mods == 0) + dwl_input_method_relay_set_focus(input_relay, client_surface(c)); #endif - /* Activate the new client */ - client_activate_surface(client_surface(c), 1); + /* Activate the new client */ + client_activate_surface(client_surface(c), 1); } void // 0.5 -focusmon(const Arg *arg) -{ - int i = 0, nmons = wl_list_length(&mons); - if (nmons) { - do /* don't switch to disabled mons */ - selmon = dirtomon(arg->i); - while (!selmon->wlr_output->enabled && i++ < nmons); - if (!selmon->wlr_output->enabled) - selmon = NULL; - } - warp_cursor_to_selmon(selmon); - focusclient(focustop(selmon), 1); +focusmon(const Arg *arg) { + int i = 0, nmons = wl_list_length(&mons); + if (nmons) { + do /* don't switch to disabled mons */ + selmon = dirtomon(arg->i); + while (!selmon->wlr_output->enabled && i++ < nmons); + if (!selmon->wlr_output->enabled) + selmon = NULL; + } + warp_cursor_to_selmon(selmon); + focusclient(focustop(selmon), 1); } -void //17 -focusstack(const Arg *arg) -{ - /* Focus the next or previous client (in tiling order) on selmon */ - Client *c, *sel = focustop(selmon); - if (!sel || sel->isfullscreen) - return; - if (arg->i > 0) { - wl_list_for_each(c, &sel->link, link) { - if (&c->link == &clients) - continue; /* wrap past the sentinel node */ - if (VISIBLEON(c, selmon)) - break; /* found it */ - } - } else { - wl_list_for_each_reverse(c, &sel->link, link) { - if (&c->link == &clients) - continue; /* wrap past the sentinel node */ - if (VISIBLEON(c, selmon)) - break; /* found it */ - } - } - /* If only one client is visible on selmon, then c == sel */ - focusclient(c, 1); +void // 17 +focusstack(const Arg *arg) { + /* Focus the next or previous client (in tiling order) on selmon */ + Client *c, *sel = focustop(selmon); + if (!sel || sel->isfullscreen) + return; + if (arg->i > 0) { + wl_list_for_each(c, &sel->link, link) { + if (&c->link == &clients) + continue; /* wrap past the sentinel node */ + if (VISIBLEON(c, selmon)) + break; /* found it */ + } + } else { + wl_list_for_each_reverse(c, &sel->link, link) { + if (&c->link == &clients) + continue; /* wrap past the sentinel node */ + if (VISIBLEON(c, selmon)) + break; /* found it */ + } + } + /* If only one client is visible on selmon, then c == sel */ + focusclient(c, 1); } /* We probably should change the name of this, it sounds like * will focus the topmost client of this mon, when actually will * only return that client */ -Client * //0.5 -focustop(Monitor *m) -{ - Client *c; - wl_list_for_each(c, &fstack, flink) { - if(c->iskilling) - continue; - if (VISIBLEON(c, m)) - return c; - } - return NULL; +Client * // 0.5 +focustop(Monitor *m) { + Client *c; + wl_list_for_each(c, &fstack, flink) { + if (c->iskilling) + continue; + if (VISIBLEON(c, m)) + return c; + } + return NULL; } void // 0.6 -fullscreennotify(struct wl_listener *listener, void *data) -{ - Client *c = wl_container_of(listener, c, fullscreen); - setfullscreen(c, client_wants_fullscreen(c)); +fullscreennotify(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, fullscreen); + setfullscreen(c, client_wants_fullscreen(c)); } -void -incnmaster(const Arg *arg) -{ - if (!arg || !selmon) - return; - selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->pertag->nmasters[selmon->pertag->curtag] + arg->i, 0); - arrange(selmon,false); +void incnmaster(const Arg *arg) { + if (!arg || !selmon) + return; + selmon->pertag->nmasters[selmon->pertag->curtag] = + MAX(selmon->pertag->nmasters[selmon->pertag->curtag] + arg->i, 0); + arrange(selmon, false); } -void -incgaps(const Arg *arg) -{ - setgaps( - selmon->gappoh + arg->i, - selmon->gappov + arg->i, - selmon->gappih + arg->i, - selmon->gappiv + arg->i - ); +void incgaps(const Arg *arg) { + setgaps(selmon->gappoh + arg->i, selmon->gappov + arg->i, + selmon->gappih + arg->i, selmon->gappiv + arg->i); } -void -incigaps(const Arg *arg) -{ - setgaps( - selmon->gappoh, - selmon->gappov, - selmon->gappih + arg->i, - selmon->gappiv + arg->i - ); +void incigaps(const Arg *arg) { + setgaps(selmon->gappoh, selmon->gappov, selmon->gappih + arg->i, + selmon->gappiv + arg->i); } -void -incihgaps(const Arg *arg) -{ - setgaps( - selmon->gappoh, - selmon->gappov, - selmon->gappih + arg->i, - selmon->gappiv - ); +void incihgaps(const Arg *arg) { + setgaps(selmon->gappoh, selmon->gappov, selmon->gappih + arg->i, + selmon->gappiv); } -void -incivgaps(const Arg *arg) -{ - setgaps( - selmon->gappoh, - selmon->gappov, - selmon->gappih, - selmon->gappiv + arg->i - ); +void incivgaps(const Arg *arg) { + setgaps(selmon->gappoh, selmon->gappov, selmon->gappih, + selmon->gappiv + arg->i); } -void -incogaps(const Arg *arg) -{ - setgaps( - selmon->gappoh + arg->i, - selmon->gappov + arg->i, - selmon->gappih, - selmon->gappiv - ); +void incogaps(const Arg *arg) { + setgaps(selmon->gappoh + arg->i, selmon->gappov + arg->i, selmon->gappih, + selmon->gappiv); } -void -incohgaps(const Arg *arg) -{ - setgaps( - selmon->gappoh + arg->i, - selmon->gappov, - selmon->gappih, - selmon->gappiv - ); +void incohgaps(const Arg *arg) { + setgaps(selmon->gappoh + arg->i, selmon->gappov, selmon->gappih, + selmon->gappiv); } -void -requestmonstate(struct wl_listener *listener, void *data) -{ - struct wlr_output_event_request_state *event = data; - wlr_output_commit_state(event->output, event->state); - updatemons(NULL, NULL); +void requestmonstate(struct wl_listener *listener, void *data) { + struct wlr_output_event_request_state *event = data; + wlr_output_commit_state(event->output, event->state); + updatemons(NULL, NULL); } - -void -incovgaps(const Arg *arg) -{ - setgaps( - selmon->gappoh, - selmon->gappov + arg->i, - selmon->gappih, - selmon->gappiv - ); +void incovgaps(const Arg *arg) { + setgaps(selmon->gappoh, selmon->gappov + arg->i, selmon->gappih, + selmon->gappiv); } -void //17 -inputdevice(struct wl_listener *listener, void *data) -{ - /* This event is raised by the backend when a new input device becomes - * available. */ - struct wlr_input_device *device = data; - uint32_t caps; +void // 17 +inputdevice(struct wl_listener *listener, void *data) { + /* This event is raised by the backend when a new input device becomes + * available. */ + struct wlr_input_device *device = data; + uint32_t caps; - switch (device->type) { - case WLR_INPUT_DEVICE_KEYBOARD: - createkeyboard(wlr_keyboard_from_input_device(device)); - break; - case WLR_INPUT_DEVICE_POINTER: - createpointer(wlr_pointer_from_input_device(device)); - break; - default: - /* TODO handle other input device types */ - break; - } + switch (device->type) { + case WLR_INPUT_DEVICE_KEYBOARD: + createkeyboard(wlr_keyboard_from_input_device(device)); + break; + case WLR_INPUT_DEVICE_POINTER: + createpointer(wlr_pointer_from_input_device(device)); + break; + default: + /* TODO handle other input device types */ + break; + } - /* We need to let the wlr_seat know what our capabilities are, which is - * communiciated to the client. In dwl we always have a cursor, even if - * there are no pointer devices, so we always include that capability. */ - /* TODO do we actually require a cursor? */ - caps = WL_SEAT_CAPABILITY_POINTER; - if (!wl_list_empty(&keyboards)) - caps |= WL_SEAT_CAPABILITY_KEYBOARD; - wlr_seat_set_capabilities(seat, caps); + /* We need to let the wlr_seat know what our capabilities are, which is + * communiciated to the client. In dwl we always have a cursor, even if + * there are no pointer devices, so we always include that capability. */ + /* TODO do we actually require a cursor? */ + caps = WL_SEAT_CAPABILITY_POINTER; + if (!wl_list_empty(&keyboards)) + caps |= WL_SEAT_CAPABILITY_KEYBOARD; + wlr_seat_set_capabilities(seat, caps); } -int -keyrepeat(void *data) -{ - Keyboard *kb = data; - int i; - if (!kb->nsyms || kb->wlr_keyboard->repeat_info.rate <= 0) - return 0; +int keyrepeat(void *data) { + Keyboard *kb = data; + int i; + if (!kb->nsyms || kb->wlr_keyboard->repeat_info.rate <= 0) + return 0; - wl_event_source_timer_update(kb->key_repeat_source, - 1000 / kb->wlr_keyboard->repeat_info.rate); + wl_event_source_timer_update(kb->key_repeat_source, + 1000 / kb->wlr_keyboard->repeat_info.rate); - for (i = 0; i < kb->nsyms; i++) - keybinding(kb->mods, kb->keysyms[i]); + for (i = 0; i < kb->nsyms; i++) + keybinding(kb->mods, kb->keysyms[i]); - return 0; + return 0; } - -int //17 -keybinding(uint32_t mods, xkb_keysym_t sym) -{ - /* - * Here we handle compositor keybindings. This is when the compositor is - * processing keys, rather than passing them on to the client for its own - * processing. - */ - int handled = 0; - const Key *k; - for (k = keys; k < END(keys); k++) { - if (CLEANMASK(mods) == CLEANMASK(k->mod) && - sym == k->keysym && k->func) { - k->func(&k->arg); - handled = 1; - } - } - return handled; +int // 17 +keybinding(uint32_t mods, xkb_keysym_t sym) { + /* + * Here we handle compositor keybindings. This is when the compositor is + * processing keys, rather than passing them on to the client for its own + * processing. + */ + int handled = 0; + const Key *k; + for (k = keys; k < END(keys); k++) { + if (CLEANMASK(mods) == CLEANMASK(k->mod) && sym == k->keysym && k->func) { + k->func(&k->arg); + handled = 1; + } + } + return handled; } -void //17 -keypress(struct wl_listener *listener, void *data) -{ - int i; - /* This event is raised when a key is pressed or released. */ - Keyboard *kb = wl_container_of(listener, kb, key); - struct wlr_keyboard_key_event *event = data; +void // 17 +keypress(struct wl_listener *listener, void *data) { + int i; + /* This event is raised when a key is pressed or released. */ + Keyboard *kb = wl_container_of(listener, kb, key); + struct wlr_keyboard_key_event *event = data; - /* Translate libinput keycode -> xkbcommon */ - uint32_t keycode = event->keycode + 8; - /* Get a list of keysyms based on the keymap for this keyboard */ - const xkb_keysym_t *syms; - int nsyms = xkb_state_key_get_syms( - kb->wlr_keyboard->xkb_state, keycode, &syms); + /* Translate libinput keycode -> xkbcommon */ + uint32_t keycode = event->keycode + 8; + /* Get a list of keysyms based on the keymap for this keyboard */ + const xkb_keysym_t *syms; + int nsyms = + xkb_state_key_get_syms(kb->wlr_keyboard->xkb_state, keycode, &syms); - int handled = 0; - uint32_t mods = wlr_keyboard_get_modifiers(kb->wlr_keyboard); + int handled = 0; + uint32_t mods = wlr_keyboard_get_modifiers(kb->wlr_keyboard); - wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); + wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); #ifdef IM - if (!locked && event->state == WL_KEYBOARD_KEY_STATE_RELEASED && (keycode == 133 ||keycode == 37 || keycode == 64 || keycode == 50 || keycode == 134 || keycode == 105 || keycode == 108 || keycode == 62) && selmon->sel) { - dwl_input_method_relay_set_focus(input_relay, client_surface(selmon->sel)); - } -#endif - - /* On _press_ if there is no active screen locker, - * attempt to process a compositor keybinding. */ - if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) - for (i = 0; i < nsyms; i++) - handled = keybinding(mods, syms[i]) || handled; - - if (handled && kb->wlr_keyboard->repeat_info.delay > 0) { - kb->mods = mods; - kb->keysyms = syms; - kb->nsyms = nsyms; - wl_event_source_timer_update(kb->key_repeat_source, - kb->wlr_keyboard->repeat_info.delay); - } else { - kb->nsyms = 0; - wl_event_source_timer_update(kb->key_repeat_source, 0); - } - - if (handled) - return; - - -#ifdef IM - /* if there is a keyboard grab, we send the key there */ - struct wlr_input_method_keyboard_grab_v2 *kb_grab = keyboard_get_im_grab(kb); - if (kb_grab) { - wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab,kb->wlr_keyboard); - wlr_input_method_keyboard_grab_v2_send_key(kb_grab,event->time_msec, event->keycode, event->state); - wlr_log(WLR_DEBUG, "keypress send to IM:%u mods %u state %u",event->keycode, mods,event->state); - return; - } + if (!locked && event->state == WL_KEYBOARD_KEY_STATE_RELEASED && + (keycode == 133 || keycode == 37 || keycode == 64 || keycode == 50 || + keycode == 134 || keycode == 105 || keycode == 108 || keycode == 62) && + selmon->sel) { + dwl_input_method_relay_set_focus(input_relay, client_surface(selmon->sel)); + } #endif - /* Pass unhandled keycodes along to the client. */ - wlr_seat_set_keyboard(seat, kb->wlr_keyboard); - wlr_seat_keyboard_notify_key(seat, event->time_msec, - event->keycode, event->state); + /* On _press_ if there is no active screen locker, + * attempt to process a compositor keybinding. */ + if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) + for (i = 0; i < nsyms; i++) + handled = keybinding(mods, syms[i]) || handled; + + if (handled && kb->wlr_keyboard->repeat_info.delay > 0) { + kb->mods = mods; + kb->keysyms = syms; + kb->nsyms = nsyms; + wl_event_source_timer_update(kb->key_repeat_source, + kb->wlr_keyboard->repeat_info.delay); + } else { + kb->nsyms = 0; + wl_event_source_timer_update(kb->key_repeat_source, 0); + } + + if (handled) + return; + +#ifdef IM + /* if there is a keyboard grab, we send the key there */ + struct wlr_input_method_keyboard_grab_v2 *kb_grab = keyboard_get_im_grab(kb); + if (kb_grab) { + wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab, kb->wlr_keyboard); + wlr_input_method_keyboard_grab_v2_send_key(kb_grab, event->time_msec, + event->keycode, event->state); + wlr_log(WLR_DEBUG, "keypress send to IM:%u mods %u state %u", + event->keycode, mods, event->state); + return; + } +#endif + + /* Pass unhandled keycodes along to the client. */ + wlr_seat_set_keyboard(seat, kb->wlr_keyboard); + wlr_seat_keyboard_notify_key(seat, event->time_msec, event->keycode, + event->state); } - -void //17 -keypressmod(struct wl_listener *listener, void *data) -{ - /* This event is raised when a modifier key, such as shift or alt, is - * pressed. We simply communicate this to the client. */ - Keyboard *kb = wl_container_of(listener, kb, modifiers); +void // 17 +keypressmod(struct wl_listener *listener, void *data) { + /* This event is raised when a modifier key, such as shift or alt, is + * pressed. We simply communicate this to the client. */ + Keyboard *kb = wl_container_of(listener, kb, modifiers); #ifdef IM - struct wlr_input_method_keyboard_grab_v2 *kb_grab = keyboard_get_im_grab(kb); - if (kb_grab) { - wlr_input_method_keyboard_grab_v2_send_modifiers(kb_grab, - &kb->wlr_keyboard->modifiers); - wlr_log(WLR_DEBUG, "keypressmod send to IM"); - return; - } + struct wlr_input_method_keyboard_grab_v2 *kb_grab = keyboard_get_im_grab(kb); + if (kb_grab) { + wlr_input_method_keyboard_grab_v2_send_modifiers( + kb_grab, &kb->wlr_keyboard->modifiers); + wlr_log(WLR_DEBUG, "keypressmod send to IM"); + return; + } #endif - /* - * A seat can only have one keyboard, but this is a limitation of the - * Wayland protocol - not wlroots. We assign all connected keyboards to the - * same seat. You can swap out the underlying wlr_keyboard like this and - * wlr_seat handles this transparently. - */ - wlr_seat_set_keyboard(seat, kb->wlr_keyboard); - /* Send modifiers to the client. */ - wlr_seat_keyboard_notify_modifiers(seat, - &kb->wlr_keyboard->modifiers); + /* + * A seat can only have one keyboard, but this is a limitation of the + * Wayland protocol - not wlroots. We assign all connected keyboards to the + * same seat. You can swap out the underlying wlr_keyboard like this and + * wlr_seat handles this transparently. + */ + wlr_seat_set_keyboard(seat, kb->wlr_keyboard); + /* Send modifiers to the client. */ + wlr_seat_keyboard_notify_modifiers(seat, &kb->wlr_keyboard->modifiers); } void pending_kill_client(Client *c) { - c->iskilling = 1; - c->animainit_geom = c->geom; - c->pending = c->geom; - c->pending.y = c->geom.y + c->mon->m.height -(c->geom.y -c->mon->m.y); + c->iskilling = 1; + c->animainit_geom = c->geom; + c->pending = c->geom; + c->pending.y = c->geom.y + c->mon->m.height - (c->geom.y - c->mon->m.y); - if (c == grabc) { - cursor_mode = CurNormal; - grabc = NULL; - } + if (c == grabc) { + cursor_mode = CurNormal; + grabc = NULL; + } - if (c == selmon->sel) { - selmon->sel = NULL; - Client *nextfocus = focustop(selmon); + if (c == selmon->sel) { + selmon->sel = NULL; + Client *nextfocus = focustop(selmon); - if(nextfocus) { - focusclient(nextfocus,0); - } + if (nextfocus) { + focusclient(nextfocus, 0); + } - if(!nextfocus && selmon->isoverview){ - Arg arg = {0}; - toggleoverview(&arg); - } - } + if (!nextfocus && selmon->isoverview) { + Arg arg = {0}; + toggleoverview(&arg); + } + } - if(c->foreign_toplevel){ - wlr_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel); - c->foreign_toplevel = NULL; - } + if (c->foreign_toplevel) { + wlr_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel); + c->foreign_toplevel = NULL; + } - resize(c,c->geom,0); - printstatus(); - motionnotify(0, NULL, 0, 0, 0, 0); - arrange(selmon,false); + resize(c, c->geom, 0); + printstatus(); + motionnotify(0, NULL, 0, 0, 0, 0); + arrange(selmon, false); } -void -killclient(const Arg *arg) -{ - Client *c; - c = selmon->sel; - if (c) { - pending_kill_client(c); - } - +void killclient(const Arg *arg) { + Client *c; + c = selmon->sel; + if (c) { + pending_kill_client(c); + } } -void //0.5 -locksession(struct wl_listener *listener, void *data) -{ - struct wlr_session_lock_v1 *session_lock = data; - SessionLock *lock; - wlr_scene_node_set_enabled(&locked_bg->node, 1); - if (cur_lock) { - wlr_session_lock_v1_destroy(session_lock); - return; - } - lock = session_lock->data = ecalloc(1, sizeof(*lock)); - focusclient(NULL, 0); +void // 0.5 +locksession(struct wl_listener *listener, void *data) { + struct wlr_session_lock_v1 *session_lock = data; + SessionLock *lock; + wlr_scene_node_set_enabled(&locked_bg->node, 1); + if (cur_lock) { + wlr_session_lock_v1_destroy(session_lock); + return; + } + lock = session_lock->data = ecalloc(1, sizeof(*lock)); + focusclient(NULL, 0); - lock->scene = wlr_scene_tree_create(layers[LyrBlock]); - cur_lock = lock->lock = session_lock; - locked = 1; + lock->scene = wlr_scene_tree_create(layers[LyrBlock]); + cur_lock = lock->lock = session_lock; + locked = 1; - LISTEN(&session_lock->events.new_surface, &lock->new_surface, createlocksurface); - LISTEN(&session_lock->events.destroy, &lock->destroy, destroysessionlock); - LISTEN(&session_lock->events.unlock, &lock->unlock, unlocksession); + LISTEN(&session_lock->events.new_surface, &lock->new_surface, + createlocksurface); + LISTEN(&session_lock->events.destroy, &lock->destroy, destroysessionlock); + LISTEN(&session_lock->events.unlock, &lock->unlock, unlocksession); - wlr_session_lock_v1_send_locked(session_lock); + wlr_session_lock_v1_send_locked(session_lock); } -void //0.5 -maplayersurfacenotify(struct wl_listener *listener, void *data) -{ - motionnotify(0, NULL, 0, 0, 0, 0); +void // 0.5 +maplayersurfacenotify(struct wl_listener *listener, void *data) { + motionnotify(0, NULL, 0, 0, 0, 0); } -void //old fix to 0.5 -mapnotify(struct wl_listener *listener, void *data) -{ - /* Called when the surface is mapped, or ready to display on-screen. */ - Client *p = NULL; - Client *c = wl_container_of(listener, c, map); - int i; - /* Create scene tree for this client and its border */ - c->scene = client_surface(c)->data = wlr_scene_tree_create(layers[LyrTile]); - wlr_scene_node_set_enabled(&c->scene->node, c->type != XDGShell); - c->scene_surface = c->type == XDGShell - ? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg) - : wlr_scene_subsurface_tree_create(c->scene, client_surface(c)); - c->scene->node.data = c->scene_surface->node.data = c; +void // old fix to 0.5 +mapnotify(struct wl_listener *listener, void *data) { + /* Called when the surface is mapped, or ready to display on-screen. */ + Client *p = NULL; + Client *c = wl_container_of(listener, c, map); + int i; + /* Create scene tree for this client and its border */ + c->scene = client_surface(c)->data = wlr_scene_tree_create(layers[LyrTile]); + wlr_scene_node_set_enabled(&c->scene->node, c->type != XDGShell); + c->scene_surface = + c->type == XDGShell + ? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg) + : wlr_scene_subsurface_tree_create(c->scene, client_surface(c)); + c->scene->node.data = c->scene_surface->node.data = c; - client_get_geometry(c, &c->geom); + client_get_geometry(c, &c->geom); - /* Handle unmanaged clients first so we can return prior create borders */ - if (client_is_unmanaged(c)) { - /* Unmanaged clients always are floating */ - wlr_scene_node_reparent(&c->scene->node, layers[LyrFloat]); - wlr_scene_node_set_position(&c->scene->node, c->geom.x + borderpx, - c->geom.y + borderpx); - if (client_wants_focus(c)) { - focusclient(c, 1); - exclusive_focus = c; - } - return; - } + /* Handle unmanaged clients first so we can return prior create borders */ + if (client_is_unmanaged(c)) { + /* Unmanaged clients always are floating */ + wlr_scene_node_reparent(&c->scene->node, layers[LyrFloat]); + wlr_scene_node_set_position(&c->scene->node, c->geom.x + borderpx, + c->geom.y + borderpx); + if (client_wants_focus(c)) { + focusclient(c, 1); + exclusive_focus = c; + } + return; + } - for (i = 0; i < 4; i++) { - c->border[i] = wlr_scene_rect_create(c->scene, 0, 0, - c->isurgent ? urgentcolor : bordercolor); - c->border[i]->node.data = c; - } + for (i = 0; i < 4; i++) { + c->border[i] = wlr_scene_rect_create( + c->scene, 0, 0, c->isurgent ? urgentcolor : bordercolor); + c->border[i]->node.data = c; + } - /* Initialize client geometry with room for border */ - client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT); - c->geom.width += 2 * c->bw; - c->geom.height += 2 * c->bw; - c->isfakefullscreen = 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->is_open_animation = true; - //nop - if (new_is_master) - // tile at the top - wl_list_insert(&clients, &c->link); //新窗口是master,头部入栈 - else - wl_list_insert(clients.prev, &c->link); //尾部入栈 - wl_list_insert(&fstack, &c->flink); + /* Initialize client geometry with room for border */ + client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | + WLR_EDGE_RIGHT); + c->geom.width += 2 * c->bw; + c->geom.height += 2 * c->bw; + c->isfakefullscreen = 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->is_open_animation = true; + // nop + if (new_is_master) + // tile at the top + wl_list_insert(&clients, &c->link); // 新窗口是master,头部入栈 + else + wl_list_insert(clients.prev, &c->link); // 尾部入栈 + wl_list_insert(&fstack, &c->flink); - /* Set initial monitor, tags, floating status, and focus: - * we always consider floating, clients that have parent and thus - * we set the same tags and monitor than its parent, if not - * try to apply rules for them */ - if ((p = client_get_parent(c))) { - c->isfloating = 1; - setmon(c, p->mon, p->tags); - } else { - applyrules(c); - } + /* Set initial monitor, tags, floating status, and focus: + * we always consider floating, clients that have parent and thus + * we set the same tags and monitor than its parent, if not + * try to apply rules for them */ + if ((p = client_get_parent(c))) { + c->isfloating = 1; + setmon(c, p->mon, p->tags); + } else { + applyrules(c); + } - //创建外部顶层窗口的句柄,每一个顶层窗口都有一个 - c->foreign_toplevel = wlr_foreign_toplevel_handle_v1_create(foreign_toplevel_manager); + // 创建外部顶层窗口的句柄,每一个顶层窗口都有一个 + c->foreign_toplevel = + wlr_foreign_toplevel_handle_v1_create(foreign_toplevel_manager); - //监听来自外部对于窗口的事件请求 - if(c->foreign_toplevel){ - LISTEN(&(c->foreign_toplevel->events.request_activate), - &c->foreign_activate_request,handle_foreign_activate_request); - LISTEN(&(c->foreign_toplevel->events.request_fullscreen), - &c->foreign_fullscreen_request,handle_foreign_fullscreen_request); - LISTEN(&(c->foreign_toplevel->events.request_close), - &c->foreign_close_request,handle_foreign_close_request); - LISTEN(&(c->foreign_toplevel->events.destroy), - &c->foreign_destroy,handle_foreign_destroy); - //设置外部顶层句柄的id为应用的id - const char *appid; - appid = client_get_appid(c) ; - if(appid) - wlr_foreign_toplevel_handle_v1_set_app_id(c->foreign_toplevel,appid); - //设置外部顶层句柄的title为应用的title - const char *title; - title = client_get_title(c) ; - if(title) - wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel,title); - //设置外部顶层句柄的显示监视器为当前监视器 - wlr_foreign_toplevel_handle_v1_output_enter( - c->foreign_toplevel, selmon->wlr_output); - } + // 监听来自外部对于窗口的事件请求 + if (c->foreign_toplevel) { + LISTEN(&(c->foreign_toplevel->events.request_activate), + &c->foreign_activate_request, handle_foreign_activate_request); + LISTEN(&(c->foreign_toplevel->events.request_fullscreen), + &c->foreign_fullscreen_request, handle_foreign_fullscreen_request); + LISTEN(&(c->foreign_toplevel->events.request_close), + &c->foreign_close_request, handle_foreign_close_request); + LISTEN(&(c->foreign_toplevel->events.destroy), &c->foreign_destroy, + handle_foreign_destroy); + // 设置外部顶层句柄的id为应用的id + const char *appid; + appid = client_get_appid(c); + if (appid) + wlr_foreign_toplevel_handle_v1_set_app_id(c->foreign_toplevel, appid); + // 设置外部顶层句柄的title为应用的title + const char *title; + title = client_get_title(c); + if (title) + wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel, title); + // 设置外部顶层句柄的显示监视器为当前监视器 + wlr_foreign_toplevel_handle_v1_output_enter(c->foreign_toplevel, + selmon->wlr_output); + } - if(selmon->sel && selmon->sel->foreign_toplevel) - wlr_foreign_toplevel_handle_v1_set_activated(selmon->sel->foreign_toplevel,false); - selmon->sel = c; - if(c->foreign_toplevel) - wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel,true); - - printstatus(); + if (selmon->sel && selmon->sel->foreign_toplevel) + wlr_foreign_toplevel_handle_v1_set_activated(selmon->sel->foreign_toplevel, + false); + selmon->sel = c; + if (c->foreign_toplevel) + wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); + printstatus(); } -void //0.5 -maximizenotify(struct wl_listener *listener, void *data) -{ - /* This event is raised when a client would like to maximize itself, - * typically because the user clicked on the maximize button on - * client-side decorations. dwl doesn't support maximization, but - * to conform to xdg-shell protocol we still must send a configure. - * Since xdg-shell protocol v5 we should ignore request of unsupported - * capabilities, just schedule a empty configure when the client uses <5 - * protocol version - * wlr_xdg_surface_schedule_configure() is used to send an empty reply. */ - // Client *c = wl_container_of(listener, c, maximize); - // 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}); - Client *c = wl_container_of(listener, c, maximize); - if(c->isfakefullscreen || c->isfullscreen) - setfakefullscreen(c, 0); - else - setfakefullscreen(c,1); - +void // 0.5 +maximizenotify(struct wl_listener *listener, void *data) { + /* This event is raised when a client would like to maximize itself, + * typically because the user clicked on the maximize button on + * client-side decorations. dwl doesn't support maximization, but + * to conform to xdg-shell protocol we still must send a configure. + * Since xdg-shell protocol v5 we should ignore request of unsupported + * capabilities, just schedule a empty configure when the client uses <5 + * protocol version + * wlr_xdg_surface_schedule_configure() is used to send an empty reply. */ + // Client *c = wl_container_of(listener, c, maximize); + // 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}); + Client *c = wl_container_of(listener, c, maximize); + if (c->isfakefullscreen || c->isfullscreen) + setfakefullscreen(c, 0); + else + setfakefullscreen(c, 1); } void set_minized(Client *c) { - if (c->isglobal) { - c->isglobal = 0; - selmon->sel->tags = selmon->tagset[selmon->seltags]; - } - c->is_scratchpad_show = 0; - c->oldtags = c->mon->sel->tags; - c->tags = 0; - c->isminied = 1; - c->is_in_scratchpad = 1; - c->is_scratchpad_show = 0; - focusclient(focustop(selmon), 1); - arrange(c->mon,false); - wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel,false); - wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel,true); - wl_list_remove(&c->link); //从原来位置移除 - wl_list_insert(clients.prev, &c->link); //插入尾部 - + if (c->isglobal) { + c->isglobal = 0; + selmon->sel->tags = selmon->tagset[selmon->seltags]; + } + c->is_scratchpad_show = 0; + c->oldtags = c->mon->sel->tags; + c->tags = 0; + c->isminied = 1; + c->is_in_scratchpad = 1; + c->is_scratchpad_show = 0; + focusclient(focustop(selmon), 1); + arrange(c->mon, false); + wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, false); + wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, true); + wl_list_remove(&c->link); // 从原来位置移除 + wl_list_insert(clients.prev, &c->link); // 插入尾部 } -void //0.5 -minimizenotify(struct wl_listener *listener, void *data) -{ - /* This event is raised when a client would like to maximize itself, - * typically because the user clicked on the maximize button on - * client-side decorations. dwl doesn't support maximization, but - * to conform to xdg-shell protocol we still must send a configure. - * Since xdg-shell protocol v5 we should ignore request of unsupported - * capabilities, just schedule a empty configure when the client uses <5 - * protocol version - * wlr_xdg_surface_schedule_configure() is used to send an empty reply. */ - // Client *c = wl_container_of(listener, c, maximize); - // 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}); - Client *c = wl_container_of(listener, c, minimize); - set_minized(c); +void // 0.5 +minimizenotify(struct wl_listener *listener, void *data) { + /* This event is raised when a client would like to maximize itself, + * typically because the user clicked on the maximize button on + * client-side decorations. dwl doesn't support maximization, but + * to conform to xdg-shell protocol we still must send a configure. + * Since xdg-shell protocol v5 we should ignore request of unsupported + * capabilities, just schedule a empty configure when the client uses <5 + * protocol version + * wlr_xdg_surface_schedule_configure() is used to send an empty reply. */ + // Client *c = wl_container_of(listener, c, maximize); + // 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}); + Client *c = wl_container_of(listener, c, minimize); + set_minized(c); } +void // 17 +monocle(Monitor *m) { + Client *c; + int n = 0; - -void //17 -monocle(Monitor *m) -{ - Client *c; - int n = 0; - - wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) - continue; - resize(c, m->w, 0); - n++; - } - if (n) - snprintf(m->ltsymbol, LENGTH(m->ltsymbol), "[%d]", n); - if ((c = focustop(m))) - wlr_scene_node_raise_to_top(&c->scene->node); + wl_list_for_each(c, &clients, link) { + if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) + continue; + resize(c, m->w, 0); + n++; + } + if (n) + snprintf(m->ltsymbol, LENGTH(m->ltsymbol), "[%d]", n); + if ((c = focustop(m))) + wlr_scene_node_raise_to_top(&c->scene->node); } -void //0.5 -motionabsolute(struct wl_listener *listener, void *data) -{ - /* This event is forwarded by the cursor when a pointer emits an _absolute_ - * motion event, from 0..1 on each axis. This happens, for example, when - * wlroots is running under a Wayland window rather than KMS+DRM, and you - * move the mouse over the window. You could enter the window from any edge, - * so we have to warp the mouse there. There is also some hardware which - * emits these events. */ - struct wlr_pointer_motion_absolute_event *event = data; - double lx, ly, dx, dy; +void // 0.5 +motionabsolute(struct wl_listener *listener, void *data) { + /* This event is forwarded by the cursor when a pointer emits an _absolute_ + * motion event, from 0..1 on each axis. This happens, for example, when + * wlroots is running under a Wayland window rather than KMS+DRM, and you + * move the mouse over the window. You could enter the window from any edge, + * so we have to warp the mouse there. There is also some hardware which + * emits these events. */ + struct wlr_pointer_motion_absolute_event *event = data; + double lx, ly, dx, dy; - if (!event->time_msec) /* this is 0 with virtual pointers */ - wlr_cursor_warp_absolute(cursor, &event->pointer->base, event->x, event->y); + if (!event->time_msec) /* this is 0 with virtual pointers */ + wlr_cursor_warp_absolute(cursor, &event->pointer->base, event->x, event->y); - wlr_cursor_absolute_to_layout_coords(cursor, &event->pointer->base, event->x, event->y, &lx, &ly); - dx = lx - cursor->x; - dy = ly - cursor->y; - motionnotify(event->time_msec, &event->pointer->base, dx, dy, dx, dy); + wlr_cursor_absolute_to_layout_coords(cursor, &event->pointer->base, event->x, + event->y, &lx, &ly); + dx = lx - cursor->x; + dy = ly - cursor->y; + motionnotify(event->time_msec, &event->pointer->base, dx, dy, dx, dy); } -void //fix for 0.5 -motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double dy, - double dx_unaccel, double dy_unaccel) -{ - double sx = 0, sy = 0, sx_confined, sy_confined; - Client *c = NULL, *w = NULL; - LayerSurface *l = NULL; - struct wlr_surface *surface = NULL; - struct wlr_pointer_constraint_v1 *constraint; +void // fix for 0.5 +motionnotify(uint32_t time, struct wlr_input_device *device, double dx, + double dy, double dx_unaccel, double dy_unaccel) { + double sx = 0, sy = 0, sx_confined, sy_confined; + Client *c = NULL, *w = NULL; + LayerSurface *l = NULL; + struct wlr_surface *surface = NULL; + struct wlr_pointer_constraint_v1 *constraint; - /* Find the client under the pointer and send the event along. */ - xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy); + /* Find the client under the pointer and send the event along. */ + xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy); - if (cursor_mode == CurPressed && !seat->drag - && surface != seat->pointer_state.focused_surface - && toplevel_from_wlr_surface(seat->pointer_state.focused_surface, &w, &l) >= 0) { - c = w; - surface = seat->pointer_state.focused_surface; - sx = cursor->x - (l ? l->geom.x : w->geom.x); - sy = cursor->y - (l ? l->geom.y : w->geom.y); - } + if (cursor_mode == CurPressed && !seat->drag && + surface != seat->pointer_state.focused_surface && + toplevel_from_wlr_surface(seat->pointer_state.focused_surface, &w, &l) >= + 0) { + c = w; + surface = seat->pointer_state.focused_surface; + sx = cursor->x - (l ? l->geom.x : w->geom.x); + sy = cursor->y - (l ? l->geom.y : w->geom.y); + } - /* time is 0 in internal calls meant to restore pointer focus. */ - if (time) { - wlr_relative_pointer_manager_v1_send_relative_motion( - relative_pointer_mgr, seat, (uint64_t)time * 1000, - dx, dy, dx_unaccel, dy_unaccel); + /* time is 0 in internal calls meant to restore pointer focus. */ + if (time) { + wlr_relative_pointer_manager_v1_send_relative_motion( + relative_pointer_mgr, seat, (uint64_t)time * 1000, dx, dy, dx_unaccel, + dy_unaccel); - wl_list_for_each(constraint, &pointer_constraints->constraints, link) - cursorconstrain(constraint); + wl_list_for_each(constraint, &pointer_constraints->constraints, link) + cursorconstrain(constraint); - if (active_constraint && cursor_mode != CurResize && cursor_mode != CurMove) { - toplevel_from_wlr_surface(active_constraint->surface, &c, NULL); - if (c && active_constraint->surface == seat->pointer_state.focused_surface) { - sx = cursor->x - c->geom.x - c->bw; - sy = cursor->y - c->geom.y - c->bw; - if (wlr_region_confine(&active_constraint->region, sx, sy, - sx + dx, sy + dy, &sx_confined, &sy_confined)) { - dx = sx_confined - sx; - dy = sy_confined - sy; - } + if (active_constraint && cursor_mode != CurResize && + cursor_mode != CurMove) { + toplevel_from_wlr_surface(active_constraint->surface, &c, NULL); + if (c && + active_constraint->surface == seat->pointer_state.focused_surface) { + sx = cursor->x - c->geom.x - c->bw; + sy = cursor->y - c->geom.y - c->bw; + if (wlr_region_confine(&active_constraint->region, sx, sy, sx + dx, + sy + dy, &sx_confined, &sy_confined)) { + dx = sx_confined - sx; + dy = sy_confined - sy; + } - if (active_constraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED) - return; - } - } + if (active_constraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED) + return; + } + } - wlr_cursor_move(cursor, device, dx, dy); - wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); + wlr_cursor_move(cursor, device, dx, dy); + wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); - /* Update selmon (even while dragging a window) */ - if (sloppyfocus) - selmon = xytomon(cursor->x, cursor->y); - } + /* Update selmon (even while dragging a window) */ + if (sloppyfocus) + selmon = xytomon(cursor->x, cursor->y); + } - /* Update drag icon's position */ - wlr_scene_node_set_position(&drag_icon->node, cursor->x, cursor->y); + /* Update drag icon's position */ + wlr_scene_node_set_position(&drag_icon->node, cursor->x, cursor->y); - /* If we are currently grabbing the mouse, handle and return */ - if (cursor_mode == CurMove) { - /* Move the grabbed client to the new position. */ - grabc->oldgeom = (struct wlr_box){.x = cursor->x - grabcx, .y = cursor->y - grabcy, - .width = grabc->geom.width, .height = grabc->geom.height}; - resize(grabc, grabc->oldgeom, 1); - return; - } else if (cursor_mode == CurResize) { - grabc->oldgeom = (struct wlr_box){.x = grabc->geom.x, .y = grabc->geom.y, - .width = cursor->x - grabc->geom.x, .height = cursor->y - grabc->geom.y}; - resize(grabc, grabc->oldgeom, 1); - return; - } + /* If we are currently grabbing the mouse, handle and return */ + if (cursor_mode == CurMove) { + /* Move the grabbed client to the new position. */ + grabc->oldgeom = (struct wlr_box){.x = cursor->x - grabcx, + .y = cursor->y - grabcy, + .width = grabc->geom.width, + .height = grabc->geom.height}; + resize(grabc, grabc->oldgeom, 1); + return; + } else if (cursor_mode == CurResize) { + grabc->oldgeom = (struct wlr_box){.x = grabc->geom.x, + .y = grabc->geom.y, + .width = cursor->x - grabc->geom.x, + .height = cursor->y - grabc->geom.y}; + resize(grabc, grabc->oldgeom, 1); + return; + } - /* If there's no client surface under the cursor, set the cursor image to a - * default. This is what makes the cursor image appear when you move it - * off of a client or over its border. */ - if (!surface && !seat->drag) - wlr_cursor_set_xcursor(cursor, cursor_mgr, "left_ptr"); + /* If there's no client surface under the cursor, set the cursor image to a + * default. This is what makes the cursor image appear when you move it + * off of a client or over its border. */ + if (!surface && !seat->drag) + wlr_cursor_set_xcursor(cursor, cursor_mgr, "left_ptr"); - pointerfocus(c, surface, sx, sy, time); + pointerfocus(c, surface, sx, sy, time); } - void // fix for 0.5 光标相对位置移动事件处理 -motionrelative(struct wl_listener *listener, void *data) -{ - /* This event is forwarded by the cursor when a pointer emits a _relative_ - * pointer motion event (i.e. a delta) */ - struct wlr_pointer_motion_event *event = data; - /* The cursor doesn't move unless we tell it to. The cursor automatically - * handles constraining the motion to the output layout, as well as any - * special configuration applied for the specific input device which - * generated the event. You can pass NULL for the device if you want to move - * the cursor around without any input. */ +motionrelative(struct wl_listener *listener, void *data) { + /* This event is forwarded by the cursor when a pointer emits a _relative_ + * pointer motion event (i.e. a delta) */ + struct wlr_pointer_motion_event *event = data; + /* The cursor doesn't move unless we tell it to. The cursor automatically + * handles constraining the motion to the output layout, as well as any + * special configuration applied for the specific input device which + * generated the event. You can pass NULL for the device if you want to move + * the cursor around without any input. */ - - // //处理一些事件,比如窗口聚焦,图层聚焦通知到客户端 - // motionnotify(event->time_msec); - // //扩展事件通知,没有这个鼠标移动的时候滑轮将无法使用 - // wlr_relative_pointer_manager_v1_send_relative_motion( - // pointer_manager, - // seat, (uint64_t)(event->time_msec) * 1000, - // event->delta_x, event->delta_y, - // event->unaccel_dx, event->unaccel_dy); - // //通知光标设备移动 - // wlr_cursor_move(cursor, &event->pointer->base, event->delta_x, event->delta_y); - motionnotify(event->time_msec, &event->pointer->base, event->delta_x, event->delta_y, - event->unaccel_dx, event->unaccel_dy); - //鼠标左下热区判断是否触发 - toggle_hotarea(cursor->x,cursor->y); + // //处理一些事件,比如窗口聚焦,图层聚焦通知到客户端 + // motionnotify(event->time_msec); + // //扩展事件通知,没有这个鼠标移动的时候滑轮将无法使用 + // wlr_relative_pointer_manager_v1_send_relative_motion( + // pointer_manager, + // seat, (uint64_t)(event->time_msec) * 1000, + // event->delta_x, event->delta_y, + // event->unaccel_dx, event->unaccel_dy); + // //通知光标设备移动 + // wlr_cursor_move(cursor, &event->pointer->base, event->delta_x, + // event->delta_y); + motionnotify(event->time_msec, &event->pointer->base, event->delta_x, + event->delta_y, event->unaccel_dx, event->unaccel_dy); + // 鼠标左下热区判断是否触发 + toggle_hotarea(cursor->x, cursor->y); } -void //17 -moveresize(const Arg *arg) -{ - if (cursor_mode != CurNormal && cursor_mode != CurPressed) - return; - xytonode(cursor->x, cursor->y, NULL, &grabc, NULL, NULL, NULL); - if (!grabc || client_is_unmanaged(grabc) || grabc->isfullscreen) - return; +void // 17 +moveresize(const Arg *arg) { + if (cursor_mode != CurNormal && cursor_mode != CurPressed) + return; + xytonode(cursor->x, cursor->y, NULL, &grabc, NULL, NULL, NULL); + if (!grabc || client_is_unmanaged(grabc) || grabc->isfullscreen) + return; - /* Float the window and tell motionnotify to grab it */ - if(grabc->isfloating == 0) { - setfloating(grabc, 1); - } - - switch (cursor_mode = arg->ui) { - case CurMove: - grabcx = cursor->x - grabc->geom.x; - grabcy = cursor->y - grabc->geom.y; - wlr_cursor_set_xcursor(cursor, cursor_mgr, "fleur"); - break; - case CurResize: - /* Doesn't work for X11 output - the next absolute motion event - * returns the cursor to where it started */ - wlr_cursor_warp_closest(cursor, NULL, - grabc->geom.x + grabc->geom.width, - grabc->geom.y + grabc->geom.height); - wlr_cursor_set_xcursor(cursor, cursor_mgr, "bottom_right_corner"); - break; - } + /* Float the window and tell motionnotify to grab it */ + if (grabc->isfloating == 0) { + setfloating(grabc, 1); + } + + switch (cursor_mode = arg->ui) { + case CurMove: + grabcx = cursor->x - grabc->geom.x; + grabcy = cursor->y - grabc->geom.y; + wlr_cursor_set_xcursor(cursor, cursor_mgr, "fleur"); + break; + case CurResize: + /* Doesn't work for X11 output - the next absolute motion event + * returns the cursor to where it started */ + wlr_cursor_warp_closest(cursor, NULL, grabc->geom.x + grabc->geom.width, + grabc->geom.y + grabc->geom.height); + wlr_cursor_set_xcursor(cursor, cursor_mgr, "bottom_right_corner"); + break; + } } -void //0.5 -outputmgrapply(struct wl_listener *listener, void *data) -{ - struct wlr_output_configuration_v1 *config = data; - outputmgrapplyortest(config, 0); +void // 0.5 +outputmgrapply(struct wl_listener *listener, void *data) { + struct wlr_output_configuration_v1 *config = data; + outputmgrapplyortest(config, 0); } -void //0.5 -outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) -{ - /* - * Called when a client such as wlr-randr requests a change in output - * configuration. This is only one way that the layout can be changed, - * so any Monitor information should be updated by updatemons() after an - * output_layout.change event, not here. - */ - struct wlr_output_configuration_head_v1 *config_head; - int ok = 1; +void // 0.5 +outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) { + /* + * Called when a client such as wlr-randr requests a change in output + * configuration. This is only one way that the layout can be changed, + * so any Monitor information should be updated by updatemons() after an + * output_layout.change event, not here. + */ + struct wlr_output_configuration_head_v1 *config_head; + int ok = 1; - wl_list_for_each(config_head, &config->heads, link) { - struct wlr_output *wlr_output = config_head->state.output; - Monitor *m = wlr_output->data; - struct wlr_output_state state; + wl_list_for_each(config_head, &config->heads, link) { + struct wlr_output *wlr_output = config_head->state.output; + Monitor *m = wlr_output->data; + struct wlr_output_state state; - wlr_output_state_init(&state); - wlr_output_state_set_enabled(&state, config_head->state.enabled); - if (!config_head->state.enabled) - goto apply_or_test; + wlr_output_state_init(&state); + wlr_output_state_set_enabled(&state, config_head->state.enabled); + if (!config_head->state.enabled) + goto apply_or_test; - if (config_head->state.mode) - wlr_output_state_set_mode(&state, config_head->state.mode); - else - wlr_output_state_set_custom_mode(&state, - config_head->state.custom_mode.width, - config_head->state.custom_mode.height, - config_head->state.custom_mode.refresh); + if (config_head->state.mode) + wlr_output_state_set_mode(&state, config_head->state.mode); + else + wlr_output_state_set_custom_mode(&state, + config_head->state.custom_mode.width, + config_head->state.custom_mode.height, + config_head->state.custom_mode.refresh); - wlr_output_state_set_transform(&state, config_head->state.transform); - wlr_output_state_set_scale(&state, config_head->state.scale); - wlr_output_state_set_adaptive_sync_enabled(&state, - config_head->state.adaptive_sync_enabled); + wlr_output_state_set_transform(&state, config_head->state.transform); + wlr_output_state_set_scale(&state, config_head->state.scale); + wlr_output_state_set_adaptive_sync_enabled( + &state, config_head->state.adaptive_sync_enabled); -apply_or_test: - ok &= test ? wlr_output_test_state(wlr_output, &state) - : wlr_output_commit_state(wlr_output, &state); + apply_or_test: + ok &= test ? wlr_output_test_state(wlr_output, &state) + : wlr_output_commit_state(wlr_output, &state); - /* Don't move monitors if position wouldn't change, this to avoid - * wlroots marking the output as manually configured. - * wlr_output_layout_add does not like disabled outputs */ - if (!test && wlr_output->enabled && (m->m.x != config_head->state.x || m->m.y != config_head->state.y)) - wlr_output_layout_add(output_layout, wlr_output, - config_head->state.x, config_head->state.y); + /* Don't move monitors if position wouldn't change, this to avoid + * wlroots marking the output as manually configured. + * wlr_output_layout_add does not like disabled outputs */ + if (!test && wlr_output->enabled && + (m->m.x != config_head->state.x || m->m.y != config_head->state.y)) + wlr_output_layout_add(output_layout, wlr_output, config_head->state.x, + config_head->state.y); - wlr_output_state_finish(&state); - } + wlr_output_state_finish(&state); + } - if (ok) - wlr_output_configuration_v1_send_succeeded(config); - else - wlr_output_configuration_v1_send_failed(config); - wlr_output_configuration_v1_destroy(config); + if (ok) + wlr_output_configuration_v1_send_succeeded(config); + else + wlr_output_configuration_v1_send_failed(config); + wlr_output_configuration_v1_destroy(config); - /* TODO: use a wrapper function? */ - updatemons(NULL, NULL); + /* TODO: use a wrapper function? */ + updatemons(NULL, NULL); } -void //0.5 -outputmgrtest(struct wl_listener *listener, void *data) -{ - struct wlr_output_configuration_v1 *config = data; - outputmgrapplyortest(config, 1); +void // 0.5 +outputmgrtest(struct wl_listener *listener, void *data) { + struct wlr_output_configuration_v1 *config = data; + outputmgrapplyortest(config, 1); } - -void //17 +void // 17 pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, - uint32_t time) -{ - struct timespec now; - int internal_call = !time; + uint32_t time) { + struct timespec now; + int internal_call = !time; - if (surface != seat->pointer_state.focused_surface && - sloppyfocus && time && c && !client_is_unmanaged(c)) - focusclient(c, 0); + if (surface != seat->pointer_state.focused_surface && sloppyfocus && time && + c && !client_is_unmanaged(c)) + focusclient(c, 0); - /* If surface is NULL, try use the focused client surface to set pointer foucs */ - if (time == 0 && !surface && selmon && selmon->sel) { - surface = client_surface(selmon->sel); - } + /* If surface is NULL, try use the focused client surface to set pointer foucs + */ + if (time == 0 && !surface && selmon && selmon->sel) { + surface = client_surface(selmon->sel); + } - /* If surface is still NULL, clear pointer focus */ - if (!surface) { - wlr_seat_pointer_notify_clear_focus(seat); - return; - } + /* If surface is still NULL, clear pointer focus */ + if (!surface) { + wlr_seat_pointer_notify_clear_focus(seat); + return; + } - if (internal_call) { - clock_gettime(CLOCK_MONOTONIC, &now); - time = now.tv_sec * 1000 + now.tv_nsec / 1000000; - } - - /* Let the client know that the mouse cursor has entered one - * of its surfaces, and make keyboard focus follow if desired. - * wlroots makes this a no-op if surface is already focused */ - wlr_seat_pointer_notify_enter(seat, surface, sx, sy); - wlr_seat_pointer_notify_motion(seat, time, sx, sy); + if (internal_call) { + clock_gettime(CLOCK_MONOTONIC, &now); + time = now.tv_sec * 1000 + now.tv_nsec / 1000000; + } + /* Let the client know that the mouse cursor has entered one + * of its surfaces, and make keyboard focus follow if desired. + * wlroots makes this a no-op if surface is already focused */ + wlr_seat_pointer_notify_enter(seat, surface, sx, sy); + wlr_seat_pointer_notify_motion(seat, time, sx, sy); } -void //17 -printstatus(void) -{ - Monitor *m = NULL; - Client *c; - uint32_t occ, urg, sel; - const char *appid, *title; +void // 17 +printstatus(void) { + Monitor *m = NULL; + Client *c; + uint32_t occ, urg, sel; + const char *appid, *title; - wl_list_for_each(m, &mons, link) { - if(!m->wlr_output->enabled) { - continue; - } - occ = urg = 0; - wl_list_for_each(c, &clients, link) { - if (c->mon != m) - continue; - occ |= c->tags; - if (c->isurgent) - urg |= c->tags; - } - if ((c = focustop(m))) { - title = client_get_title(c); - appid = client_get_appid(c); - printf("%s title %s\n", m->wlr_output->name, title ? title : broken); - printf("%s appid %s\n", m->wlr_output->name, appid ? appid : broken); - printf("%s fullscreen %u\n", m->wlr_output->name, c->isfullscreen); - printf("%s floating %u\n", m->wlr_output->name, c->isfloating); - sel = c->tags; - } else { - printf("%s title \n", m->wlr_output->name); - printf("%s appid \n", m->wlr_output->name); - printf("%s fullscreen \n", m->wlr_output->name); - printf("%s floating \n", m->wlr_output->name); - sel = 0; - } + wl_list_for_each(m, &mons, link) { + if (!m->wlr_output->enabled) { + continue; + } + occ = urg = 0; + wl_list_for_each(c, &clients, link) { + if (c->mon != m) + continue; + occ |= c->tags; + if (c->isurgent) + urg |= c->tags; + } + if ((c = focustop(m))) { + title = client_get_title(c); + appid = client_get_appid(c); + printf("%s title %s\n", m->wlr_output->name, title ? title : broken); + printf("%s appid %s\n", m->wlr_output->name, appid ? appid : broken); + printf("%s fullscreen %u\n", m->wlr_output->name, c->isfullscreen); + printf("%s floating %u\n", m->wlr_output->name, c->isfloating); + sel = c->tags; + } else { + printf("%s title \n", m->wlr_output->name); + printf("%s appid \n", m->wlr_output->name); + printf("%s fullscreen \n", m->wlr_output->name); + printf("%s floating \n", m->wlr_output->name); + sel = 0; + } - printf("%s selmon %u\n", m->wlr_output->name, m == selmon); - printf("%s tags %u %u %u %u\n", m->wlr_output->name, occ, m->tagset[m->seltags], - sel, urg); - printf("%s layout %s\n", m->wlr_output->name, m->ltsymbol); - dwl_ipc_output_printstatus(m); //更新waybar上tag的状态 这里很关键 - } - fflush(stdout); + printf("%s selmon %u\n", m->wlr_output->name, m == selmon); + printf("%s tags %u %u %u %u\n", m->wlr_output->name, occ, + m->tagset[m->seltags], sel, urg); + printf("%s layout %s\n", m->wlr_output->name, m->ltsymbol); + dwl_ipc_output_printstatus(m); // 更新waybar上tag的状态 这里很关键 + } + fflush(stdout); } -void //0.5 -quit(const Arg *arg) -{ - wl_display_terminate(dpy); +void // 0.5 +quit(const Arg *arg) { + wl_display_terminate(dpy); } -void -quitsignal(int signo) -{ - quit(NULL); -} +void quitsignal(int signo) { quit(NULL); } -void -scene_buffer_apply_opacity(struct wlr_scene_buffer *buffer, - int sx, int sy, void *data) { +void scene_buffer_apply_opacity(struct wlr_scene_buffer *buffer, int sx, int sy, + void *data) { wlr_scene_buffer_set_opacity(buffer, *(double *)data); } void client_set_opacity(Client *c, double opacity) { - wlr_scene_node_for_each_buffer(&c->scene_surface->node, scene_buffer_apply_opacity, &opacity); + wlr_scene_node_for_each_buffer(&c->scene_surface->node, + scene_buffer_apply_opacity, &opacity); } -void -client_handle_opacity(Client *c) { - if (!c || !c->mon || !client_surface(c)->mapped) - return; +void client_handle_opacity(Client *c) { + if (!c || !c->mon || !client_surface(c)->mapped) + return; - double opacity = c->isfullscreen || c->isfakefullscreen - ? 1.0 - : c == selmon->sel - ? 0.8 - : 0.5; + double opacity = c->isfullscreen || c->isfakefullscreen ? 1.0 + : c == selmon->sel ? 0.8 + : 0.5; - wlr_scene_node_for_each_buffer(&c->scene_surface->node, scene_buffer_apply_opacity, &opacity); + wlr_scene_node_for_each_buffer(&c->scene_surface->node, + scene_buffer_apply_opacity, &opacity); } void // 0.5 -rendermon(struct wl_listener *listener, void *data) -{ - /* This function is called every time an output is ready to display a frame, - * generally at the output's refresh rate (e.g. 60Hz). */ - Monitor *m = wl_container_of(listener, m, frame); - Client *c; - struct wlr_output_state pending = {0}; - struct wlr_gamma_control_v1 *gamma_control; - struct timespec now; - bool need_more_frames = false; +rendermon(struct wl_listener *listener, void *data) { + /* This function is called every time an output is ready to display a frame, + * generally at the output's refresh rate (e.g. 60Hz). */ + Monitor *m = wl_container_of(listener, m, frame); + Client *c; + struct wlr_output_state pending = {0}; + struct wlr_gamma_control_v1 *gamma_control; + struct timespec now; + bool need_more_frames = false; - /* Render if no XDG clients have an outstanding resize and are visible on - * this monitor. */ - // wl_list_for_each(c, &clients, link) { - // if (c->resize && !c->isfloating && client_is_rendered_on_mon(c, m) && !client_is_stopped(c)) - // goto skip; - // } + /* Render if no XDG clients have an outstanding resize and are visible on + * this monitor. */ + // wl_list_for_each(c, &clients, link) { + // if (c->resize && !c->isfloating && client_is_rendered_on_mon(c, m) && + // !client_is_stopped(c)) goto skip; + // } - wl_list_for_each(c, &clients, link) - { - // if (client_is_rendered_on_mon(c, m) && !client_is_stopped(c)) - need_more_frames = client_draw_frame(c); - // the opacity is usabel, but don't enable temporarily - // client_handle_opacity(c); - } + wl_list_for_each(c, &clients, link) { + // if (client_is_rendered_on_mon(c, m) && !client_is_stopped(c)) + need_more_frames = client_draw_frame(c); + // the opacity is usabel, but don't enable temporarily + // client_handle_opacity(c); + } - if (need_more_frames) - { - wlr_output_schedule_frame(m->wlr_output); - } + if (need_more_frames) { + wlr_output_schedule_frame(m->wlr_output); + } + /* + * HACK: The "correct" way to set the gamma is to commit it together with + * the rest of the state in one go, but to do that we would need to rewrite + * wlr_scene_output_commit() in order to add the gamma to the pending + * state before committing, instead try to commit the gamma in one frame, + * and commit the rest of the state in the next one (or in the same frame if + * the gamma can not be committed). + */ + if (m->gamma_lut_changed) { + gamma_control = wlr_gamma_control_manager_v1_get_control(gamma_control_mgr, + m->wlr_output); + m->gamma_lut_changed = 0; - /* - * HACK: The "correct" way to set the gamma is to commit it together with - * the rest of the state in one go, but to do that we would need to rewrite - * wlr_scene_output_commit() in order to add the gamma to the pending - * state before committing, instead try to commit the gamma in one frame, - * and commit the rest of the state in the next one (or in the same frame if - * the gamma can not be committed). - */ - if (m->gamma_lut_changed) - { - gamma_control = wlr_gamma_control_manager_v1_get_control(gamma_control_mgr, m->wlr_output); - m->gamma_lut_changed = 0; + if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) + goto commit; - if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) - goto commit; + if (!wlr_output_test_state(m->wlr_output, &pending)) { + wlr_gamma_control_v1_send_failed_and_destroy(gamma_control); + goto commit; + } + wlr_output_commit_state(m->wlr_output, &pending); + wlr_output_schedule_frame(m->wlr_output); + } else { + commit: + wlr_scene_output_commit(m->scene_output, NULL); + } - if (!wlr_output_test_state(m->wlr_output, &pending)) - { - wlr_gamma_control_v1_send_failed_and_destroy(gamma_control); - goto commit; - } - wlr_output_commit_state(m->wlr_output, &pending); - wlr_output_schedule_frame(m->wlr_output); - } - else - { - commit: - wlr_scene_output_commit(m->scene_output, NULL); - } + // skip: + // /* Let clients know a frame has been rendered */ + // clock_gettime(CLOCK_MONOTONIC, &now); + // wlr_scene_output_send_frame_done(m->scene_output, &now); + // wlr_output_state_finish(&pending); + struct wlr_scene_output *scene_output = + wlr_scene_get_scene_output(scene, m->wlr_output); - // skip: - // /* Let clients know a frame has been rendered */ - // clock_gettime(CLOCK_MONOTONIC, &now); - // wlr_scene_output_send_frame_done(m->scene_output, &now); - // wlr_output_state_finish(&pending); - struct wlr_scene_output *scene_output = wlr_scene_get_scene_output(scene, m->wlr_output); + wlr_scene_output_commit(scene_output, NULL); - wlr_scene_output_commit(scene_output, NULL); + // struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); - // struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - - wlr_scene_output_send_frame_done(scene_output, &now); - wlr_output_state_finish(&pending); + wlr_scene_output_send_frame_done(scene_output, &now); + wlr_output_state_finish(&pending); } -void //0.5 -requestdecorationmode(struct wl_listener *listener, void *data) -{ - Client *c = wl_container_of(listener, c, set_decoration_mode); - wlr_xdg_toplevel_decoration_v1_set_mode(c->decoration, - WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); +void // 0.5 +requestdecorationmode(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, set_decoration_mode); + wlr_xdg_toplevel_decoration_v1_set_mode( + c->decoration, WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); } -void //17 -requeststartdrag(struct wl_listener *listener, void *data) -{ - struct wlr_seat_request_start_drag_event *event = data; +void // 17 +requeststartdrag(struct wl_listener *listener, void *data) { + struct wlr_seat_request_start_drag_event *event = data; - if (wlr_seat_validate_pointer_grab_serial(seat, event->origin, - event->serial)) - wlr_seat_start_pointer_drag(seat, event->drag, event->serial); - else - wlr_data_source_destroy(event->drag->source); + if (wlr_seat_validate_pointer_grab_serial(seat, event->origin, event->serial)) + wlr_seat_start_pointer_drag(seat, event->drag, event->serial); + else + wlr_data_source_destroy(event->drag->source); } - -void //为了兼容dwm代码封装的 -resizeclient(Client *c,int x,int y,int w,int h, int interact) -{ - struct wlr_box tmp_box; - c->prev = c->geom; - tmp_box.x = x; - tmp_box.y = y; - tmp_box.width = w; - tmp_box.height = h; - resize(c, tmp_box, interact); +void // 为了兼容dwm代码封装的 +resizeclient(Client *c, int x, int y, int w, int h, int interact) { + struct wlr_box tmp_box; + c->prev = c->geom; + tmp_box.x = x; + tmp_box.y = y; + tmp_box.width = w; + tmp_box.height = h; + resize(c, tmp_box, interact); } - -void setborder_color(Client *c){ - unsigned int i; - if(!c || !c->mon) - return; - if (c->isurgent) { - for (i = 0; i < 4; i++) - wlr_scene_rect_set_color(c->border[i], urgentcolor); - } if (c->is_in_scratchpad && c == selmon->sel) { - for (i = 0; i < 4; i++) - wlr_scene_rect_set_color(c->border[i], scratchpadcolor); - } 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){ - for (i = 0; i < 4; i++) - wlr_scene_rect_set_color(c->border[i], fakefullscreencolor); - } else if(c == selmon->sel) { - for (i = 0; i < 4; i++) - wlr_scene_rect_set_color(c->border[i], focuscolor); - } else { - for (i = 0; i < 4; i++) - wlr_scene_rect_set_color(c->border[i], bordercolor); - } +void setborder_color(Client *c) { + unsigned int i; + if (!c || !c->mon) + return; + if (c->isurgent) { + for (i = 0; i < 4; i++) + wlr_scene_rect_set_color(c->border[i], urgentcolor); + } + if (c->is_in_scratchpad && c == selmon->sel) { + for (i = 0; i < 4; i++) + wlr_scene_rect_set_color(c->border[i], scratchpadcolor); + } 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) { + for (i = 0; i < 4; i++) + wlr_scene_rect_set_color(c->border[i], fakefullscreencolor); + } else if (c == selmon->sel) { + for (i = 0; i < 4; i++) + wlr_scene_rect_set_color(c->border[i], focuscolor); + } else { + for (i = 0; i < 4; i++) + wlr_scene_rect_set_color(c->border[i], bordercolor); + } } void exchange_two_client(Client *c1, Client *c2) { @@ -3670,39 +3619,40 @@ void exchange_two_client(Client *c1, Client *c2) { struct wl_list *tmp1_next = c1->link.next; struct wl_list *tmp2_next = c2->link.next; - // wl_list 是双向链表,其中clients是头部节点,它的下一个节点是第一个客户端的链表节点 - //最后一个客户端的链表节点的下一个节点也指向clients,但clients本身不是客户端的链表节点 - //客户端遍历从clients的下一个节点开始,到检测到客户端节点的下一个是clients结束 - + // wl_list + // 是双向链表,其中clients是头部节点,它的下一个节点是第一个客户端的链表节点 + // 最后一个客户端的链表节点的下一个节点也指向clients,但clients本身不是客户端的链表节点 + // 客户端遍历从clients的下一个节点开始,到检测到客户端节点的下一个是clients结束 + // 当c1和c2为相邻节点时 if (c1->link.next == &c2->link) { c1->link.next = c2->link.next; - c1->link.prev = &c2->link; + c1->link.prev = &c2->link; c2->link.next = &c1->link; - c2->link.prev = tmp1_prev; + c2->link.prev = tmp1_prev; tmp1_prev->next = &c2->link; - tmp2_next->prev = &c1->link; + tmp2_next->prev = &c1->link; } else if (c2->link.next == &c1->link) { c2->link.next = c1->link.next; - c2->link.prev = &c1->link; + c2->link.prev = &c1->link; c1->link.next = &c2->link; - c1->link.prev = tmp2_prev; + c1->link.prev = tmp2_prev; tmp2_prev->next = &c1->link; - tmp1_next->prev = &c2->link; + tmp1_next->prev = &c2->link; } else { // 不为相邻节点 c2->link.next = tmp1_next; - c2->link.prev = tmp1_prev; + c2->link.prev = tmp1_prev; c1->link.next = tmp2_next; - c1->link.prev = tmp2_prev; + c1->link.prev = tmp2_prev; - tmp1_prev->next = &c2->link; - tmp1_next->prev = &c2->link; - tmp2_prev->next = &c1->link; - tmp2_next->prev = &c1->link; + tmp1_prev->next = &c2->link; + tmp1_next->prev = &c2->link; + tmp2_prev->next = &c1->link; + tmp2_next->prev = &c1->link; } - arrange(c1->mon,false); - focusclient(c1,0); + arrange(c1->mon, false); + focusclient(c1, 0); } void exchange_client(const Arg *arg) { @@ -3713,862 +3663,855 @@ void exchange_client(const Arg *arg) { } int is_special_animaiton_rule(Client *c) { - int visible_client_number = 0; - Client *count_c; - wl_list_for_each(count_c, &clients, link) { - if (count_c && VISIBLEON(count_c,selmon) && !count_c->isminied && !count_c->iskilling){ - visible_client_number++; - } - } + int visible_client_number = 0; + Client *count_c; + wl_list_for_each(count_c, &clients, link) { + if (count_c && VISIBLEON(count_c, selmon) && !count_c->isminied && + !count_c->iskilling) { + visible_client_number++; + } + } - if (visible_client_number < 2 && !c->isfloating) { - return DOWN; - } else if (visible_client_number == 2 && !c->isfloating && !new_is_master) { - return RIGHT; - } else if (!c->isfloating && new_is_master) { - return LEFT; - } else { - return UNDIR; - } + if (visible_client_number < 2 && !c->isfloating) { + return DOWN; + } else if (visible_client_number == 2 && !c->isfloating && !new_is_master) { + return RIGHT; + } else if (!c->isfloating && new_is_master) { + return LEFT; + } else { + return UNDIR; + } } void set_open_animaiton(Client *c, struct wlr_box geo) { - int slide_direction; - int horizontal,horizontal_value; - int vertical,vertical_value; - int special_direction; - int center_x,center_y; - if (strcmp(animation_type, "zoom") == 0 || (c->animation_type && strcmp(c->animation_type, "zoom") == 0)) { - c->animainit_geom.width = geo.width * zoom_initial_ratio; - c->animainit_geom.height = geo.height * zoom_initial_ratio; - c->animainit_geom.x = geo.x + (geo.width - c->animainit_geom.width)/2; - c->animainit_geom.y = geo.y + (geo.height - c->animainit_geom.height)/2; - return; - } else { - special_direction = is_special_animaiton_rule(c); - center_x = c->geom.x + c->geom.width/2; - center_y = c->geom.y + c->geom.height/2; - if (special_direction == UNDIR) { - horizontal = c->mon->w.x + c->mon->w.width - center_x < center_x - c->mon->w.x ? RIGHT : LEFT; - horizontal_value = horizontal == LEFT ? center_x - c->mon->w.x : c->mon->w.x + c->mon->w.width - center_x; - vertical = c->mon->w.y + c->mon->w.height - center_y < center_y - c->mon->w.y ? DOWN : UP; - vertical_value = vertical == UP ? center_y - c->mon->w.y : c->mon->w.y + c->mon->w.height - center_y; - slide_direction = horizontal_value < vertical_value ? horizontal : vertical; - } else { - slide_direction = special_direction; - } - c->animainit_geom.width = c->geom.width; - c->animainit_geom.height = c->geom.height; - switch (slide_direction) - { - case UP: - c->animainit_geom.x = c->geom.x; - c->animainit_geom.y = c->mon->m.y - c->geom.height; - break; - case DOWN: - c->animainit_geom.x = c->geom.x; - c->animainit_geom.y = c->geom.y + c->mon->m.height -(c->geom.y -c->mon->m.y); - break; - case LEFT: - c->animainit_geom.x = c->mon->m.x - c->geom.width; - c->animainit_geom.y = c->geom.y; - break; - case RIGHT: - c->animainit_geom.x = c->geom.x + c->mon->m.width -(c->geom.x -c->mon->m.x); - c->animainit_geom.y = c->geom.y; - break; - default: - c->animainit_geom.x = c->geom.x; - c->animainit_geom.y = 0 - c->geom.height; - } - } + int slide_direction; + int horizontal, horizontal_value; + int vertical, vertical_value; + int special_direction; + int center_x, center_y; + if (strcmp(animation_type, "zoom") == 0 || + (c->animation_type && strcmp(c->animation_type, "zoom") == 0)) { + c->animainit_geom.width = geo.width * zoom_initial_ratio; + c->animainit_geom.height = geo.height * zoom_initial_ratio; + c->animainit_geom.x = geo.x + (geo.width - c->animainit_geom.width) / 2; + c->animainit_geom.y = geo.y + (geo.height - c->animainit_geom.height) / 2; + return; + } else { + special_direction = is_special_animaiton_rule(c); + center_x = c->geom.x + c->geom.width / 2; + center_y = c->geom.y + c->geom.height / 2; + if (special_direction == UNDIR) { + horizontal = + c->mon->w.x + c->mon->w.width - center_x < center_x - c->mon->w.x + ? RIGHT + : LEFT; + horizontal_value = horizontal == LEFT + ? center_x - c->mon->w.x + : c->mon->w.x + c->mon->w.width - center_x; + vertical = + c->mon->w.y + c->mon->w.height - center_y < center_y - c->mon->w.y + ? DOWN + : UP; + vertical_value = vertical == UP + ? center_y - c->mon->w.y + : c->mon->w.y + c->mon->w.height - center_y; + slide_direction = + horizontal_value < vertical_value ? horizontal : vertical; + } else { + slide_direction = special_direction; + } + c->animainit_geom.width = c->geom.width; + c->animainit_geom.height = c->geom.height; + switch (slide_direction) { + case UP: + c->animainit_geom.x = c->geom.x; + c->animainit_geom.y = c->mon->m.y - c->geom.height; + break; + case DOWN: + c->animainit_geom.x = c->geom.x; + c->animainit_geom.y = + c->geom.y + c->mon->m.height - (c->geom.y - c->mon->m.y); + break; + case LEFT: + c->animainit_geom.x = c->mon->m.x - c->geom.width; + c->animainit_geom.y = c->geom.y; + break; + case RIGHT: + c->animainit_geom.x = + c->geom.x + c->mon->m.width - (c->geom.x - c->mon->m.x); + c->animainit_geom.y = c->geom.y; + break; + default: + c->animainit_geom.x = c->geom.x; + c->animainit_geom.y = 0 - c->geom.height; + } + } } -void -resize(Client *c, struct wlr_box geo, int interact) -{ +void resize(Client *c, struct wlr_box geo, int interact) { - // 动画设置的起始函数,这里用来计算一些动画的起始值 - // 动画起始位置大小是由于c->animainit_geom确定的 + // 动画设置的起始函数,这里用来计算一些动画的起始值 + // 动画起始位置大小是由于c->animainit_geom确定的 - if (!c || !c->mon || !client_surface(c)->mapped) - return; + if (!c || !c->mon || !client_surface(c)->mapped) + return; - struct wlr_box *bbox,oldgeom; - // struct wlr_box clip; - - if (!c->mon) - return; - oldgeom = c->geom; - bbox = interact ? &sgeom : &c->mon->w; - client_set_bounds(c, geo.width, geo.height); //去掉这个推荐的窗口大小,因为有时推荐的窗口特别大导致平铺异常 - c->geom = geo; - applybounds(c, bbox);//去掉这个推荐的窗口大小,因为有时推荐的窗口特别大导致平铺异常 + struct wlr_box *bbox, oldgeom; + // struct wlr_box clip; - if(!c->is_open_animation) { - c->animation.begin_fade_in = false; - client_set_opacity(c,1); - } + if (!c->mon) + return; + oldgeom = c->geom; + bbox = interact ? &sgeom : &c->mon->w; + client_set_bounds( + c, geo.width, + geo.height); // 去掉这个推荐的窗口大小,因为有时推荐的窗口特别大导致平铺异常 + c->geom = geo; + applybounds( + c, bbox); // 去掉这个推荐的窗口大小,因为有时推荐的窗口特别大导致平铺异常 - if(c->iskilling) { - c->animation.duration = animation_duration_close; - } else if(c->animation.tagouting) { - c->animation.duration = animation_duration_tag; - } else if(c->animation.tagining) { - c->animation.duration = animation_duration_tag; - } else if(c->is_open_animation) { - c->animation.duration = animation_duration_open; - } else { - c->animation.duration = animation_duration_move; - } + if (!c->is_open_animation) { + c->animation.begin_fade_in = false; + client_set_opacity(c, 1); + } - // 动画起始位置大小设置 - 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; - }else if(c->is_open_animation) { - set_open_animaiton(c,c->geom); - } else { - c->animainit_geom = oldgeom; - } + if (c->iskilling) { + c->animation.duration = animation_duration_close; + } else if (c->animation.tagouting) { + c->animation.duration = animation_duration_tag; + } else if (c->animation.tagining) { + c->animation.duration = animation_duration_tag; + } else if (c->is_open_animation) { + c->animation.duration = animation_duration_open; + } else { + c->animation.duration = animation_duration_move; + } + // 动画起始位置大小设置 + 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; + } else if (c->is_open_animation) { + set_open_animaiton(c, c->geom); + } else { + c->animainit_geom = oldgeom; + } - if(c->isnoborder || c->iskilling) { - c->bw = 0; - } - - // c->geom 是真实的窗口大小和位置,跟过度的动画无关,用于计算布局 - c->resize = client_set_size(c, c->geom.width - 2 * c->bw, - c->geom.height - 2 * c->bw); + if (c->isnoborder || c->iskilling) { + c->bw = 0; + } - // 如果不是工作区切换时划出去的窗口,就让动画的结束位置,就是上面的真实位置和大小 - // c->pending 决定动画的终点,一般在其他调用resize的函数的附近设置了 - if(!c->animation.tagouting && !c->iskilling) { - c->pending = c->geom; - } - // 开始应用动画设置 - client_set_pending_state(c); + // c->geom 是真实的窗口大小和位置,跟过度的动画无关,用于计算布局 + c->resize = + client_set_size(c, c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw); - setborder_color(c); + // 如果不是工作区切换时划出去的窗口,就让动画的结束位置,就是上面的真实位置和大小 + // c->pending 决定动画的终点,一般在其他调用resize的函数的附近设置了 + if (!c->animation.tagouting && !c->iskilling) { + c->pending = c->geom; + } + // 开始应用动画设置 + client_set_pending_state(c); + + setborder_color(c); } -void //17 -run(char *startup_cmd) +void // 17 +run(char *startup_cmd) { + /* Add a Unix socket to the Wayland display. */ + const char *socket = wl_display_add_socket_auto(dpy); + if (!socket) + die("startup: display_add_socket_auto"); + setenv("WAYLAND_DISPLAY", socket, 1); + + /* Start the backend. This will enumerate outputs and inputs, become the DRM + * master, etc */ + if (!wlr_backend_start(backend)) + die("startup: backend_start"); + + /* Now that the socket exists and the backend is started, run the startup + * command */ + autostartexec(); + if (startup_cmd) { + int piperw[2]; + if (pipe(piperw) < 0) + die("startup: pipe:"); + if ((child_pid = fork()) < 0) + die("startup: fork:"); + if (child_pid == 0) { + dup2(piperw[0], STDIN_FILENO); + close(piperw[0]); + close(piperw[1]); + execl("/bin/sh", "/bin/sh", "-c", startup_cmd, NULL); + die("startup: execl:"); + } + dup2(piperw[1], STDOUT_FILENO); + close(piperw[1]); + close(piperw[0]); + } + printstatus(); + + /* At this point the outputs are initialized, choose initial selmon based on + * cursor position, and set default cursor image */ + selmon = xytomon(cursor->x, cursor->y); + + /* TODO hack to get cursor to display in its initial location (100, 100) + * instead of (0, 0) and then jumping. still may not be fully + * initialized, as the image/coordinates are not transformed for the + * monitor when displayed here */ + wlr_cursor_warp_closest(cursor, NULL, cursor->x, cursor->y); + wlr_cursor_set_xcursor(cursor, cursor_mgr, "left_ptr"); + + /* Run the Wayland event loop. This does not return until you exit the + * compositor. Starting the backend rigged up all of the necessary event + * loop configuration to listen to libinput events, DRM events, generate + * frame events at the refresh rate, and so on. */ + wl_display_run(dpy); +} + +void setcursor(struct wl_listener *listener, void *data) { + /* This event is raised by the seat when a client provides a cursor image */ + struct wlr_seat_pointer_request_set_cursor_event *event = data; + /* If we're "grabbing" the cursor, don't use the client's image, we will + * restore it after "grabbing" sending a leave event, followed by a enter + * event, which will result in the client requesting set the cursor surface */ + if (cursor_mode != CurNormal && cursor_mode != CurPressed) + return; + /* This can be sent by any client, so we check to make sure this one is + * actually has pointer focus first. If so, we can tell the cursor to + * use the provided surface as the cursor image. It will set the + * hardware cursor on the output that it's currently on and continue to + * do so as the cursor moves between outputs. */ + if (event->seat_client == seat->pointer_state.focused_client) { + wlr_cursor_set_surface(cursor, event->surface, event->hotspot_x, + event->hotspot_y); + } +} + +void // 0.5 +setfloating(Client *c, int floating) { + + Client *fc; + int hit; + struct wlr_box target_box, backup_box; + c->isfloating = floating; + + if (!c || !c->mon || !client_surface(c)->mapped) + return; + + wlr_scene_node_reparent(&c->scene->node, + layers[c->isfloating ? LyrFloat : LyrTile]); + + target_box = c->geom; + + if (floating == 1) { + if (c->istiled) { + target_box.height = target_box.height * 0.8; + target_box.width = target_box.width * 0.8; + } + // 重新计算居中的坐标 + target_box = setclient_coordinate_center(target_box); + backup_box = c->geom; + hit = applyrulesgeom(c); + target_box = hit == 1 ? c->geom : target_box; + c->geom = backup_box; + if (c->oldgeom.width > 0 && c->oldgeom.height > 0) { + resize(c, c->oldgeom, 0); + } else { + resize(c, target_box, 0); + } + c->istiled = 0; + } else { + c->istiled = 1; + c->is_scratchpad_show = 0; + c->is_in_scratchpad = 0; + // 让当前tag中的全屏窗口退出全屏参与平铺 + wl_list_for_each(fc, &clients, + link) if (fc && c->tags & fc->tags && ISFULLSCREEN(fc)) { + clear_fullscreen_flag(fc); + } + } + + arrange(c->mon, false); + printstatus(); +} + +void setfakefullscreen(Client *c, int fakefullscreen) { + struct wlr_box fakefullscreen_box; + if (!c || !c->mon || !client_surface(c)->mapped) + return; + + c->isfakefullscreen = fakefullscreen; + + // c->bw = fullscreen ? 0 : borderpx; + // client_set_fullscreen(c, fakefullscreen); + wlr_scene_node_reparent(&c->scene->node, layers[fakefullscreen ? LyrTile + : c->isfloating ? LyrFloat + : LyrTile]); + + if (fakefullscreen) { + if (c->isfloating) + c->oldgeom = c->geom; + if (selmon->isoverview) { + Arg arg = {0}; + toggleoverview(&arg); + } + + 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; + wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层 + resize(c, fakefullscreen_box, 0); + c->isfakefullscreen = 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->isfullscreen = 0; + client_set_fullscreen(c, false); + if (c->isfloating) + setfloating(c, 1); + arrange(c->mon, false); + } +} + +void setfullscreen(Client *c, int fullscreen) // 用自定义全屏代理自带全屏 { - /* Add a Unix socket to the Wayland display. */ - const char *socket = wl_display_add_socket_auto(dpy); - if (!socket) - die("startup: display_add_socket_auto"); - setenv("WAYLAND_DISPLAY", socket, 1); + c->isfullscreen = fullscreen; - /* Start the backend. This will enumerate outputs and inputs, become the DRM - * master, etc */ - if (!wlr_backend_start(backend)) - die("startup: backend_start"); + if (!c || !c->mon || !client_surface(c)->mapped) + return; - /* Now that the socket exists and the backend is started, run the startup command */ - autostartexec(); - if (startup_cmd) { - int piperw[2]; - if (pipe(piperw) < 0) - die("startup: pipe:"); - if ((child_pid = fork()) < 0) - die("startup: fork:"); - if (child_pid == 0) { - dup2(piperw[0], STDIN_FILENO); - close(piperw[0]); - close(piperw[1]); - execl("/bin/sh", "/bin/sh", "-c", startup_cmd, NULL); - die("startup: execl:"); - } - dup2(piperw[1], STDOUT_FILENO); - close(piperw[1]); - close(piperw[0]); - } - printstatus(); + client_set_fullscreen(c, fullscreen); + wlr_scene_node_reparent(&c->scene->node, layers[fullscreen ? LyrTile + : c->isfloating ? LyrFloat + : LyrTile]); - /* At this point the outputs are initialized, choose initial selmon based on - * cursor position, and set default cursor image */ - selmon = xytomon(cursor->x, cursor->y); + if (fullscreen) { + if (c->isfloating) + c->oldgeom = c->geom; + if (selmon->isoverview) { + Arg arg = {0}; + toggleoverview(&arg); + } - /* TODO hack to get cursor to display in its initial location (100, 100) - * instead of (0, 0) and then jumping. still may not be fully - * initialized, as the image/coordinates are not transformed for the - * monitor when displayed here */ - wlr_cursor_warp_closest(cursor, NULL, cursor->x, cursor->y); - wlr_cursor_set_xcursor(cursor, cursor_mgr, "left_ptr"); - - /* Run the Wayland event loop. This does not return until you exit the - * compositor. Starting the backend rigged up all of the necessary event - * loop configuration to listen to libinput events, DRM events, generate - * frame events at the refresh rate, and so on. */ - wl_display_run(dpy); + c->bw = 0; + wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层 + resize(c, c->mon->m, 0); + c->isfullscreen = 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->isfullscreen = 0; + c->isfullscreen = 0; + c->isfakefullscreen = 0; + if (c->isfloating) + setfloating(c, 1); + arrange(c->mon, false); + } } -void -setcursor(struct wl_listener *listener, void *data) -{ - /* This event is raised by the seat when a client provides a cursor image */ - struct wlr_seat_pointer_request_set_cursor_event *event = data; - /* If we're "grabbing" the cursor, don't use the client's image, we will - * restore it after "grabbing" sending a leave event, followed by a enter - * event, which will result in the client requesting set the cursor surface */ - if (cursor_mode != CurNormal && cursor_mode != CurPressed) - return; - /* This can be sent by any client, so we check to make sure this one is - * actually has pointer focus first. If so, we can tell the cursor to - * use the provided surface as the cursor image. It will set the - * hardware cursor on the output that it's currently on and continue to - * do so as the cursor moves between outputs. */ - if (event->seat_client == seat->pointer_state.focused_client){ - wlr_cursor_set_surface(cursor, event->surface, - event->hotspot_x, event->hotspot_y); - } - +void setgaps(int oh, int ov, int ih, int iv) { + selmon->gappoh = MAX(oh, 0); + selmon->gappov = MAX(ov, 0); + selmon->gappih = MAX(ih, 0); + selmon->gappiv = MAX(iv, 0); + arrange(selmon, false); } -void //0.5 -setfloating(Client *c, int floating) -{ - - Client *fc; - int hit; - struct wlr_box target_box,backup_box; - c->isfloating = floating; - - - if (!c || !c->mon || !client_surface(c)->mapped) - return; - - wlr_scene_node_reparent(&c->scene->node, layers[c->isfloating ? LyrFloat : LyrTile]); - - target_box = c->geom; - - if (floating == 1) { - if(c->istiled) { - target_box.height = target_box.height * 0.8; - target_box.width = target_box.width * 0.8; - } - //重新计算居中的坐标 - target_box = setclient_coordinate_center(target_box); - backup_box = c->geom; - hit =applyrulesgeom(c); - target_box = hit == 1 ? c->geom : target_box; - c->geom = backup_box; - if (c->oldgeom.width > 0 && c->oldgeom.height >0) { - resize(c,c->oldgeom,0); - } else { - resize(c,target_box,0); - } - c->istiled = 0; - } else { - c->istiled = 1; - c->is_scratchpad_show = 0; - c->is_in_scratchpad = 0; - //让当前tag中的全屏窗口退出全屏参与平铺 - wl_list_for_each(fc, &clients, link) - if (fc && c->tags & fc->tags && ISFULLSCREEN(fc)) { - clear_fullscreen_flag(fc); - } - } - - arrange(c->mon,false); - printstatus(); +void // 17 +setlayout(const Arg *arg) { + if (!selmon) + return; + if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) + selmon->sellt ^= 1; + if (arg && arg->v) { + selmon->lt[selmon->sellt] = (Layout *)arg->v; + selmon->pertag->sellts[selmon->pertag->curtag] = selmon->sellt; + selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = + selmon->lt[selmon->sellt]; + } + strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, + LENGTH(selmon->ltsymbol)); + arrange(selmon, false); + printstatus(); } -void -setfakefullscreen(Client *c, int fakefullscreen) -{ - struct wlr_box fakefullscreen_box; - if (!c || !c->mon || !client_surface(c)->mapped) - return; - - c->isfakefullscreen = fakefullscreen; +void switch_layout(const Arg *arg) { + if (!selmon) + return; - // c->bw = fullscreen ? 0 : borderpx; - // client_set_fullscreen(c, fakefullscreen); - wlr_scene_node_reparent(&c->scene->node, layers[fakefullscreen - ? LyrTile : c->isfloating ? LyrFloat : LyrTile]); + selmon->sellt ^= 1; + selmon->pertag->sellts[selmon->pertag->curtag] = selmon->sellt; - if (fakefullscreen) { - if (c->isfloating) - c->oldgeom = c->geom; - if (selmon->isoverview) { - Arg arg = {0}; - toggleoverview(&arg); - } - - 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; - wlr_scene_node_raise_to_top(&c->scene->node); //将视图提升到顶层 - resize(c, fakefullscreen_box, 0); - c->isfakefullscreen = 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->isfullscreen = 0; - client_set_fullscreen(c, false); - if (c->isfloating) setfloating(c,1); - arrange(c->mon,false); - } -} - -void -setfullscreen(Client *c, int fullscreen) //用自定义全屏代理自带全屏 -{ - c->isfullscreen = fullscreen; - - if (!c || !c->mon || !client_surface(c)->mapped) - return; - - client_set_fullscreen(c, fullscreen); - wlr_scene_node_reparent(&c->scene->node, layers[fullscreen - ? LyrTile : c->isfloating ? LyrFloat : LyrTile]); - - if (fullscreen) { - if (c->isfloating) - c->oldgeom = c->geom; - if (selmon->isoverview) { - Arg arg = {0}; - toggleoverview(&arg); - } - - c->bw = 0; - wlr_scene_node_raise_to_top(&c->scene->node); //将视图提升到顶层 - resize(c, c->mon->m, 0); - c->isfullscreen = 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->isfullscreen = 0; - c->isfullscreen = 0; - c->isfakefullscreen = 0; - if (c->isfloating) setfloating(c,1); - arrange(c->mon,false); - } -} - - -void -setgaps(int oh, int ov, int ih, int iv) -{ - selmon->gappoh = MAX(oh, 0); - selmon->gappov = MAX(ov, 0); - selmon->gappih = MAX(ih, 0); - selmon->gappiv = MAX(iv, 0); - arrange(selmon,false); -} - -void //17 -setlayout(const Arg *arg) -{ - if (!selmon) - return; - if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) - selmon->sellt ^= 1; - if (arg && arg->v) { - selmon->lt[selmon->sellt] = (Layout *)arg->v; - selmon->pertag->sellts[selmon->pertag->curtag] = selmon->sellt; - selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = selmon->lt[selmon->sellt]; - } - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, LENGTH(selmon->ltsymbol)); - arrange(selmon,false); - printstatus(); -} - - -void -switch_layout(const Arg *arg) -{ - if (!selmon) - return; - - selmon->sellt ^= 1; - selmon->pertag->sellts[selmon->pertag->curtag] = selmon->sellt; - - /* TODO change layout symbol? */ - arrange(selmon,false); - printstatus(); + /* TODO change layout symbol? */ + arrange(selmon, false); + printstatus(); } /* arg > 1.0 will set mfact absolutely */ /* arg > 1.0 will set mfact absolutely */ -void //17 -setmfact(const Arg *arg) -{ - float f; +void // 17 +setmfact(const Arg *arg) { + float f; - if (!arg || !selmon || !selmon->lt[selmon->sellt]->arrange) - return; - f = arg->f < 1.0 ? arg->f + selmon->pertag->mfacts[selmon->pertag->curtag] : arg->f - 1.0; - if (f < 0.1 || f > 0.9) - return; - // selmon->mfact = f; - selmon->pertag->mfacts[selmon->pertag->curtag] = f; - arrange(selmon,false); + if (!arg || !selmon || !selmon->lt[selmon->sellt]->arrange) + return; + f = arg->f < 1.0 ? arg->f + selmon->pertag->mfacts[selmon->pertag->curtag] + : arg->f - 1.0; + if (f < 0.1 || f > 0.9) + return; + // selmon->mfact = f; + selmon->pertag->mfacts[selmon->pertag->curtag] = f; + arrange(selmon, false); } -void //0.5 -setmon(Client *c, Monitor *m, uint32_t newtags) -{ - Monitor *oldmon = c->mon; +void // 0.5 +setmon(Client *c, Monitor *m, uint32_t newtags) { + Monitor *oldmon = c->mon; - if (oldmon == m) - return; - c->mon = m; - c->prev = c->geom; + if (oldmon == m) + return; + c->mon = m; + c->prev = c->geom; - /* Scene graph sends surface leave/enter events on move and resize */ - if (oldmon) - arrange(oldmon,false); - if (m) { - /* Make sure window actually overlaps with the monitor */ - resize(c, c->geom, 0); - c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */ - setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */ - setfloating(c, c->isfloating); - } - focusclient(focustop(selmon), 1); + /* Scene graph sends surface leave/enter events on move and resize */ + if (oldmon) + arrange(oldmon, false); + if (m) { + /* Make sure window actually overlaps with the monitor */ + resize(c, c->geom, 0); + c->tags = newtags + ? newtags + : m->tagset[m->seltags]; /* assign tags of target monitor */ + setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */ + setfloating(c, c->isfloating); + } + focusclient(focustop(selmon), 1); } -void //17 -setpsel(struct wl_listener *listener, void *data) -{ - /* This event is raised by the seat when a client wants to set the selection, - * usually when the user copies something. wlroots allows compositors to - * ignore such requests if they so choose, but in dwl we always honor - */ - struct wlr_seat_request_set_primary_selection_event *event = data; - wlr_seat_set_primary_selection(seat, event->source, event->serial); +void // 17 +setpsel(struct wl_listener *listener, void *data) { + /* This event is raised by the seat when a client wants to set the selection, + * usually when the user copies something. wlroots allows compositors to + * ignore such requests if they so choose, but in dwl we always honor + */ + struct wlr_seat_request_set_primary_selection_event *event = data; + wlr_seat_set_primary_selection(seat, event->source, event->serial); } -void //17 -setsel(struct wl_listener *listener, void *data) -{ - /* This event is raised by the seat when a client wants to set the selection, - * usually when the user copies something. wlroots allows compositors to - * ignore such requests if they so choose, but in dwl we always honor - */ - struct wlr_seat_request_set_selection_event *event = data; - wlr_seat_set_selection(seat, event->source, event->serial); +void // 17 +setsel(struct wl_listener *listener, void *data) { + /* This event is raised by the seat when a client wants to set the selection, + * usually when the user copies something. wlroots allows compositors to + * ignore such requests if they so choose, but in dwl we always honor + */ + struct wlr_seat_request_set_selection_event *event = data; + wlr_seat_set_selection(seat, event->source, event->serial); } -//获取tags中最坐标的tag的tagmask -unsigned int -get_tags_first_tag(unsigned int tags){ - unsigned int i,target,tag; - tag = 0; - for(i=0;!(tag & 1);i++){ - tag = tags >> i; - } - target = 1 << (i-1); - return target; +// 获取tags中最坐标的tag的tagmask +unsigned int get_tags_first_tag(unsigned int tags) { + unsigned int i, target, tag; + tag = 0; + for (i = 0; !(tag & 1); i++) { + tag = tags >> i; + } + target = 1 << (i - 1); + return target; } void show_hide_client(Client *c) { - unsigned int target = get_tags_first_tag(c->oldtags); - tag_client(&(Arg){.ui = target},c); - // c->tags = c->oldtags; - c->isminied = 0; - wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel,false); - focusclient(c,1); - wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel,true); + unsigned int target = get_tags_first_tag(c->oldtags); + tag_client(&(Arg){.ui = target}, c); + // c->tags = c->oldtags; + c->isminied = 0; + wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, false); + focusclient(c, 1); + wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); } -void -handle_foreign_activate_request(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, foreign_activate_request); - unsigned int target; - if(c && !c->isminied && c == selmon->sel) { - set_minized(c); - return; - } +void handle_foreign_activate_request(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, foreign_activate_request); + unsigned int target; + if (c && !c->isminied && c == selmon->sel) { + set_minized(c); + return; + } - if(c->isminied) { - c->is_in_scratchpad = 0; - c->is_scratchpad_show = 0; - setborder_color(c); - show_hide_client(c); - return; - } - - target = get_tags_first_tag(c->tags); - view(&(Arg){.ui = target},true); - focusclient(c,1); - wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel,true); + if (c->isminied) { + c->is_in_scratchpad = 0; + c->is_scratchpad_show = 0; + setborder_color(c); + show_hide_client(c); + return; + } + target = get_tags_first_tag(c->tags); + view(&(Arg){.ui = target}, true); + focusclient(c, 1); + wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); } -void -handle_foreign_fullscreen_request( - struct wl_listener *listener, void *data) { - return; +void handle_foreign_fullscreen_request(struct wl_listener *listener, + void *data) { + return; } -void -handle_foreign_close_request(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, foreign_close_request); - if(c) { - pending_kill_client(c); - } +void handle_foreign_close_request(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, foreign_close_request); + if (c) { + pending_kill_client(c); + } } -void -handle_foreign_destroy(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, foreign_destroy); - if(c){ - wl_list_remove(&c->foreign_activate_request.link); - wl_list_remove(&c->foreign_fullscreen_request.link); - wl_list_remove(&c->foreign_close_request.link); - wl_list_remove(&c->foreign_destroy.link); - } +void handle_foreign_destroy(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, foreign_destroy); + if (c) { + wl_list_remove(&c->foreign_activate_request.link); + wl_list_remove(&c->foreign_fullscreen_request.link); + wl_list_remove(&c->foreign_close_request.link); + wl_list_remove(&c->foreign_destroy.link); + } } -void -setup(void) -{ - init_baked_points(); +void setup(void) { + init_baked_points(); - int i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE}; - struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig}; - sigemptyset(&sa.sa_mask); + int i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE}; + struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig}; + sigemptyset(&sa.sa_mask); - for (i = 0; i < LENGTH(sig); i++) - sigaction(sig[i], &sa, NULL); + for (i = 0; i < LENGTH(sig); i++) + sigaction(sig[i], &sa, NULL); - wlr_log_init(log_level, NULL); + wlr_log_init(log_level, NULL); - /* The Wayland display is managed by libwayland. It handles accepting - * clients from the Unix socket, manging Wayland globals, and so on. */ - dpy = wl_display_create(); - pointer_manager = wlr_relative_pointer_manager_v1_create(dpy); - /* The backend is a wlroots feature which abstracts the underlying input and - * output hardware. The autocreate option will choose the most suitable - * backend based on the current environment, such as opening an X11 window - * if an X11 server is running. The NULL argument here optionally allows you - * to pass in a custom renderer if wlr_renderer doesn't meet your needs. The - * backend uses the renderer, for example, to fall back to software cursors - * if the backend does not support hardware cursors (some older GPUs - * don't). */ - if (!(backend = wlr_backend_autocreate(dpy, &session))) - die("couldn't create backend"); + /* The Wayland display is managed by libwayland. It handles accepting + * clients from the Unix socket, manging Wayland globals, and so on. */ + dpy = wl_display_create(); + pointer_manager = wlr_relative_pointer_manager_v1_create(dpy); + /* The backend is a wlroots feature which abstracts the underlying input and + * output hardware. The autocreate option will choose the most suitable + * backend based on the current environment, such as opening an X11 window + * if an X11 server is running. The NULL argument here optionally allows you + * to pass in a custom renderer if wlr_renderer doesn't meet your needs. The + * backend uses the renderer, for example, to fall back to software cursors + * if the backend does not support hardware cursors (some older GPUs + * don't). */ + if (!(backend = wlr_backend_autocreate(dpy, &session))) + die("couldn't create backend"); - /* Initialize the scene graph used to lay out windows */ - scene = wlr_scene_create(); - for (i = 0; i < NUM_LAYERS; i++) - layers[i] = wlr_scene_tree_create(&scene->tree); - drag_icon = wlr_scene_tree_create(&scene->tree); - wlr_scene_node_place_below(&drag_icon->node, &layers[LyrBlock]->node); + /* Initialize the scene graph used to lay out windows */ + scene = wlr_scene_create(); + for (i = 0; i < NUM_LAYERS; i++) + layers[i] = wlr_scene_tree_create(&scene->tree); + drag_icon = wlr_scene_tree_create(&scene->tree); + wlr_scene_node_place_below(&drag_icon->node, &layers[LyrBlock]->node); - /* Create a renderer with the default implementation */ - if (!(drw = wlr_renderer_autocreate(backend))) - die("couldn't create renderer"); + /* Create a renderer with the default implementation */ + if (!(drw = wlr_renderer_autocreate(backend))) + die("couldn't create renderer"); - /* Create shm, drm and linux_dmabuf interfaces by ourselves. - * The simplest way is call: - * wlr_renderer_init_wl_display(drw); - * but we need to create manually the linux_dmabuf interface to integrate it - * with wlr_scene. */ - wlr_renderer_init_wl_shm(drw, dpy); + /* Create shm, drm and linux_dmabuf interfaces by ourselves. + * The simplest way is call: + * wlr_renderer_init_wl_display(drw); + * but we need to create manually the linux_dmabuf interface to integrate it + * with wlr_scene. */ + wlr_renderer_init_wl_shm(drw, dpy); - if (wlr_renderer_get_dmabuf_texture_formats(drw)) { - wlr_drm_create(dpy, drw); - wlr_scene_set_linux_dmabuf_v1(scene, - wlr_linux_dmabuf_v1_create_with_renderer(dpy, 4, drw)); - } + if (wlr_renderer_get_dmabuf_texture_formats(drw)) { + wlr_drm_create(dpy, drw); + wlr_scene_set_linux_dmabuf_v1( + scene, wlr_linux_dmabuf_v1_create_with_renderer(dpy, 4, drw)); + } - /* Create a default allocator */ - if (!(alloc = wlr_allocator_autocreate(backend, drw))) - die("couldn't create allocator"); + /* Create a default allocator */ + if (!(alloc = wlr_allocator_autocreate(backend, drw))) + die("couldn't create allocator"); - /* This creates some hands-off wlroots interfaces. The compositor is - * necessary for clients to allocate surfaces and the data device manager - * handles the clipboard. Each of these wlroots interfaces has room for you - * to dig your fingers in and play with their behavior if you want. Note that - * the clients cannot set the selection directly without compositor approval, - * see the setsel() function. */ - compositor = wlr_compositor_create(dpy, 6, drw); - wlr_export_dmabuf_manager_v1_create(dpy); - wlr_screencopy_manager_v1_create(dpy); - wlr_data_control_manager_v1_create(dpy); - wlr_data_device_manager_create(dpy); - wlr_primary_selection_v1_device_manager_create(dpy); - wlr_viewporter_create(dpy); - wlr_single_pixel_buffer_manager_v1_create(dpy); - wlr_fractional_scale_manager_v1_create(dpy, 1); - wlr_subcompositor_create(dpy); + /* This creates some hands-off wlroots interfaces. The compositor is + * necessary for clients to allocate surfaces and the data device manager + * handles the clipboard. Each of these wlroots interfaces has room for you + * to dig your fingers in and play with their behavior if you want. Note that + * the clients cannot set the selection directly without compositor approval, + * see the setsel() function. */ + compositor = wlr_compositor_create(dpy, 6, drw); + wlr_export_dmabuf_manager_v1_create(dpy); + wlr_screencopy_manager_v1_create(dpy); + wlr_data_control_manager_v1_create(dpy); + wlr_data_device_manager_create(dpy); + wlr_primary_selection_v1_device_manager_create(dpy); + wlr_viewporter_create(dpy); + wlr_single_pixel_buffer_manager_v1_create(dpy); + wlr_fractional_scale_manager_v1_create(dpy, 1); + wlr_subcompositor_create(dpy); - /* Initializes the interface used to implement urgency hints */ - activation = wlr_xdg_activation_v1_create(dpy); - LISTEN_STATIC(&activation->events.request_activate, urgent); + /* Initializes the interface used to implement urgency hints */ + activation = wlr_xdg_activation_v1_create(dpy); + LISTEN_STATIC(&activation->events.request_activate, urgent); - gamma_control_mgr = wlr_gamma_control_manager_v1_create(dpy); - LISTEN_STATIC(&gamma_control_mgr->events.set_gamma, setgamma); + gamma_control_mgr = wlr_gamma_control_manager_v1_create(dpy); + LISTEN_STATIC(&gamma_control_mgr->events.set_gamma, setgamma); - /* Creates an output layout, which a wlroots utility for working with an - * arrangement of screens in a physical layout. */ - output_layout = wlr_output_layout_create(); - LISTEN_STATIC(&output_layout->events.change, updatemons); - wlr_xdg_output_manager_v1_create(dpy, output_layout); + /* Creates an output layout, which a wlroots utility for working with an + * arrangement of screens in a physical layout. */ + output_layout = wlr_output_layout_create(); + LISTEN_STATIC(&output_layout->events.change, updatemons); + wlr_xdg_output_manager_v1_create(dpy, output_layout); - /* Configure a listener to be notified when new outputs are available on the - * backend. */ - wl_list_init(&mons); - LISTEN_STATIC(&backend->events.new_output, createmon); + /* Configure a listener to be notified when new outputs are available on the + * backend. */ + wl_list_init(&mons); + LISTEN_STATIC(&backend->events.new_output, createmon); - /* Set up our client lists and the xdg-shell. The xdg-shell is a - * Wayland protocol which is used for application windows. For more - * detail on shells, refer to the article: - * - * https://drewdevault.com/2018/07/29/Wayland-shells.html - */ - wl_list_init(&clients); - wl_list_init(&fstack); + /* Set up our client lists and the xdg-shell. The xdg-shell is a + * Wayland protocol which is used for application windows. For more + * detail on shells, refer to the article: + * + * https://drewdevault.com/2018/07/29/Wayland-shells.html + */ + wl_list_init(&clients); + wl_list_init(&fstack); - idle_notifier = wlr_idle_notifier_v1_create(dpy); + idle_notifier = wlr_idle_notifier_v1_create(dpy); - idle_inhibit_mgr = wlr_idle_inhibit_v1_create(dpy); - LISTEN_STATIC(&idle_inhibit_mgr->events.new_inhibitor, createidleinhibitor); + idle_inhibit_mgr = wlr_idle_inhibit_v1_create(dpy); + LISTEN_STATIC(&idle_inhibit_mgr->events.new_inhibitor, createidleinhibitor); - layer_shell = wlr_layer_shell_v1_create(dpy, 3); - LISTEN_STATIC(&layer_shell->events.new_surface, createlayersurface); + layer_shell = wlr_layer_shell_v1_create(dpy, 3); + LISTEN_STATIC(&layer_shell->events.new_surface, createlayersurface); - xdg_shell = wlr_xdg_shell_create(dpy, 6); - LISTEN_STATIC(&xdg_shell->events.new_surface, createnotify); + xdg_shell = wlr_xdg_shell_create(dpy, 6); + LISTEN_STATIC(&xdg_shell->events.new_surface, createnotify); - session_lock_mgr = wlr_session_lock_manager_v1_create(dpy); - wl_signal_add(&session_lock_mgr->events.new_lock, &lock_listener); - LISTEN_STATIC(&session_lock_mgr->events.destroy, destroysessionmgr); - locked_bg = wlr_scene_rect_create(layers[LyrBlock], sgeom.width, sgeom.height, - (float [4]){0.1, 0.1, 0.1, 1.0}); - wlr_scene_node_set_enabled(&locked_bg->node, 0); + session_lock_mgr = wlr_session_lock_manager_v1_create(dpy); + wl_signal_add(&session_lock_mgr->events.new_lock, &lock_listener); + LISTEN_STATIC(&session_lock_mgr->events.destroy, destroysessionmgr); + locked_bg = wlr_scene_rect_create(layers[LyrBlock], sgeom.width, sgeom.height, + (float[4]){0.1, 0.1, 0.1, 1.0}); + wlr_scene_node_set_enabled(&locked_bg->node, 0); - /* Use decoration protocols to negotiate server-side decorations */ - wlr_server_decoration_manager_set_default_mode( - wlr_server_decoration_manager_create(dpy), - WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); - xdg_decoration_mgr = wlr_xdg_decoration_manager_v1_create(dpy); - LISTEN_STATIC(&xdg_decoration_mgr->events.new_toplevel_decoration, createdecoration); - pointer_constraints = wlr_pointer_constraints_v1_create(dpy); - LISTEN_STATIC(&pointer_constraints->events.new_constraint, createpointerconstraint); + /* Use decoration protocols to negotiate server-side decorations */ + wlr_server_decoration_manager_set_default_mode( + wlr_server_decoration_manager_create(dpy), + WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); + xdg_decoration_mgr = wlr_xdg_decoration_manager_v1_create(dpy); + LISTEN_STATIC(&xdg_decoration_mgr->events.new_toplevel_decoration, + createdecoration); + pointer_constraints = wlr_pointer_constraints_v1_create(dpy); + LISTEN_STATIC(&pointer_constraints->events.new_constraint, + createpointerconstraint); - relative_pointer_mgr = wlr_relative_pointer_manager_v1_create(dpy); + relative_pointer_mgr = wlr_relative_pointer_manager_v1_create(dpy); - /* - * Creates a cursor, which is a wlroots utility for tracking the cursor - * image shown on screen. - */ - cursor = wlr_cursor_create(); - wlr_cursor_attach_output_layout(cursor, output_layout); + /* + * Creates a cursor, which is a wlroots utility for tracking the cursor + * image shown on screen. + */ + cursor = wlr_cursor_create(); + wlr_cursor_attach_output_layout(cursor, output_layout); - /* Creates an xcursor manager, another wlroots utility which loads up - * Xcursor themes to source cursor images from and makes sure that cursor - * images are available at all scale factors on the screen (necessary for - * HiDPI support). Scaled cursors will be loaded with each output. */ - // cursor_mgr = wlr_xcursor_manager_create(cursor_theme, 24); - cursor_mgr = wlr_xcursor_manager_create(NULL, 24); - setenv("XCURSOR_SIZE", "24", 1); + /* Creates an xcursor manager, another wlroots utility which loads up + * Xcursor themes to source cursor images from and makes sure that cursor + * images are available at all scale factors on the screen (necessary for + * HiDPI support). Scaled cursors will be loaded with each output. */ + // cursor_mgr = wlr_xcursor_manager_create(cursor_theme, 24); + cursor_mgr = wlr_xcursor_manager_create(NULL, 24); + setenv("XCURSOR_SIZE", "24", 1); - /* - * wlr_cursor *only* displays an image on screen. It does not move around - * when the pointer moves. However, we can attach input devices to it, and - * it will generate aggregate events for all of them. In these events, we - * can choose how we want to process them, forwarding them to clients and - * moving the cursor around. More detail on this process is described in my - * input handling blog post: - * - * https://drewdevault.com/2018/07/17/Input-handling-in-wlroots.html - * - * And more comments are sprinkled throughout the notify functions above. - */ - LISTEN_STATIC(&cursor->events.motion, motionrelative); - LISTEN_STATIC(&cursor->events.motion_absolute, motionabsolute); - LISTEN_STATIC(&cursor->events.button, buttonpress); - LISTEN_STATIC(&cursor->events.axis, axisnotify); - LISTEN_STATIC(&cursor->events.frame, cursorframe); + /* + * wlr_cursor *only* displays an image on screen. It does not move around + * when the pointer moves. However, we can attach input devices to it, and + * it will generate aggregate events for all of them. In these events, we + * can choose how we want to process them, forwarding them to clients and + * moving the cursor around. More detail on this process is described in my + * input handling blog post: + * + * https://drewdevault.com/2018/07/17/Input-handling-in-wlroots.html + * + * And more comments are sprinkled throughout the notify functions above. + */ + LISTEN_STATIC(&cursor->events.motion, motionrelative); + LISTEN_STATIC(&cursor->events.motion_absolute, motionabsolute); + LISTEN_STATIC(&cursor->events.button, buttonpress); + LISTEN_STATIC(&cursor->events.axis, axisnotify); + LISTEN_STATIC(&cursor->events.frame, cursorframe); - //这两句代码会造成obs窗口里的鼠标光标消失,不知道注释有什么影响 - cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1); - LISTEN_STATIC(&cursor_shape_mgr->events.request_set_shape, setcursorshape); + // 这两句代码会造成obs窗口里的鼠标光标消失,不知道注释有什么影响 + cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1); + LISTEN_STATIC(&cursor_shape_mgr->events.request_set_shape, setcursorshape); - /* - * Configures a seat, which is a single "seat" at which a user sits and - * operates the computer. This conceptually includes up to one keyboard, - * pointer, touch, and drawing tablet device. We also rig up a listener to - * let us know when new input devices are available on the backend. - */ - wl_list_init(&keyboards); - LISTEN_STATIC(&backend->events.new_input, inputdevice); - virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(dpy); - LISTEN_STATIC(&virtual_keyboard_mgr->events.new_virtual_keyboard, virtualkeyboard); - virtual_pointer_mgr = wlr_virtual_pointer_manager_v1_create(dpy); - LISTEN_STATIC(&virtual_pointer_mgr->events.new_virtual_pointer, virtualpointer); + /* + * Configures a seat, which is a single "seat" at which a user sits and + * operates the computer. This conceptually includes up to one keyboard, + * pointer, touch, and drawing tablet device. We also rig up a listener to + * let us know when new input devices are available on the backend. + */ + wl_list_init(&keyboards); + LISTEN_STATIC(&backend->events.new_input, inputdevice); + virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(dpy); + LISTEN_STATIC(&virtual_keyboard_mgr->events.new_virtual_keyboard, + virtualkeyboard); + virtual_pointer_mgr = wlr_virtual_pointer_manager_v1_create(dpy); + LISTEN_STATIC(&virtual_pointer_mgr->events.new_virtual_pointer, + virtualpointer); - seat = wlr_seat_create(dpy, "seat0"); - LISTEN_STATIC(&seat->events.request_set_cursor, setcursor); - LISTEN_STATIC(&seat->events.request_set_selection, setsel); - LISTEN_STATIC(&seat->events.request_set_primary_selection, setpsel); - LISTEN_STATIC(&seat->events.request_start_drag, requeststartdrag); - LISTEN_STATIC(&seat->events.start_drag, startdrag); + seat = wlr_seat_create(dpy, "seat0"); + LISTEN_STATIC(&seat->events.request_set_cursor, setcursor); + LISTEN_STATIC(&seat->events.request_set_selection, setsel); + LISTEN_STATIC(&seat->events.request_set_primary_selection, setpsel); + LISTEN_STATIC(&seat->events.request_start_drag, requeststartdrag); + LISTEN_STATIC(&seat->events.start_drag, startdrag); - output_mgr = wlr_output_manager_v1_create(dpy); - LISTEN_STATIC(&output_mgr->events.apply, outputmgrapply); - LISTEN_STATIC(&output_mgr->events.test, outputmgrtest); + output_mgr = wlr_output_manager_v1_create(dpy); + LISTEN_STATIC(&output_mgr->events.apply, outputmgrapply); + LISTEN_STATIC(&output_mgr->events.test, outputmgrtest); - wlr_scene_set_presentation(scene, wlr_presentation_create(dpy, backend)); + wlr_scene_set_presentation(scene, wlr_presentation_create(dpy, backend)); #ifdef IM - /* create text_input-, and input_method-protocol relevant globals */ - input_method_manager = wlr_input_method_manager_v2_create(dpy); - text_input_manager = wlr_text_input_manager_v3_create(dpy); + /* create text_input-, and input_method-protocol relevant globals */ + input_method_manager = wlr_input_method_manager_v2_create(dpy); + text_input_manager = wlr_text_input_manager_v3_create(dpy); - input_relay = calloc(1, sizeof(*input_relay)); - dwl_input_method_relay_init(input_relay); + input_relay = calloc(1, sizeof(*input_relay)); + dwl_input_method_relay_init(input_relay); #endif - wl_global_create(dpy, &zdwl_ipc_manager_v2_interface, 1, NULL, dwl_ipc_manager_bind); + wl_global_create(dpy, &zdwl_ipc_manager_v2_interface, 1, NULL, + dwl_ipc_manager_bind); - //创建顶层管理句柄 - foreign_toplevel_manager =wlr_foreign_toplevel_manager_v1_create(dpy); - struct wlr_xdg_foreign_registry *foreign_registry = wlr_xdg_foreign_registry_create(dpy); - wlr_xdg_foreign_v1_create(dpy, foreign_registry); - wlr_xdg_foreign_v2_create(dpy, foreign_registry); + // 创建顶层管理句柄 + foreign_toplevel_manager = wlr_foreign_toplevel_manager_v1_create(dpy); + struct wlr_xdg_foreign_registry *foreign_registry = + wlr_xdg_foreign_registry_create(dpy); + wlr_xdg_foreign_v1_create(dpy, foreign_registry); + wlr_xdg_foreign_v2_create(dpy, foreign_registry); #ifdef XWAYLAND - /* - * Initialise the XWayland X server. - * It will be started when the first X client is started. - */ - xwayland = wlr_xwayland_create(dpy, compositor, 1); - if (xwayland) { - LISTEN_STATIC(&xwayland->events.ready, xwaylandready); - LISTEN_STATIC(&xwayland->events.new_surface, createnotifyx11); + /* + * Initialise the XWayland X server. + * It will be started when the first X client is started. + */ + xwayland = wlr_xwayland_create(dpy, compositor, 1); + if (xwayland) { + LISTEN_STATIC(&xwayland->events.ready, xwaylandready); + LISTEN_STATIC(&xwayland->events.new_surface, createnotifyx11); - setenv("DISPLAY", xwayland->display_name, 1); - } else { - fprintf(stderr, "failed to setup XWayland X server, continuing without it\n"); - } + setenv("DISPLAY", xwayland->display_name, 1); + } else { + fprintf(stderr, + "failed to setup XWayland X server, continuing without it\n"); + } #endif } -void -sigchld(int unused) -{ - siginfo_t in; - /* We should be able to remove this function in favor of a simple - * struct sigaction sa = {.sa_handler = SIG_IGN}; - * sigaction(SIGCHLD, &sa, NULL); - * but the Xwayland implementation in wlroots currently prevents us from - * setting our own disposition for SIGCHLD. - */ - /* WNOWAIT leaves the child in a waitable state, in case this is the - * XWayland process - */ - while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid +void sigchld(int unused) { + siginfo_t in; + /* We should be able to remove this function in favor of a simple + * struct sigaction sa = {.sa_handler = SIG_IGN}; + * sigaction(SIGCHLD, &sa, NULL); + * but the Xwayland implementation in wlroots currently prevents us from + * setting our own disposition for SIGCHLD. + */ + /* WNOWAIT leaves the child in a waitable state, in case this is the + * XWayland process + */ + while (!waitid(P_ALL, 0, &in, WEXITED | WNOHANG | WNOWAIT) && in.si_pid #ifdef XWAYLAND - && (!xwayland || in.si_pid != xwayland->server->pid) + && (!xwayland || in.si_pid != xwayland->server->pid) #endif - ) { - pid_t *p, *lim; - waitpid(in.si_pid, NULL, 0); - if (in.si_pid == child_pid) - child_pid = -1; - if (!(p = autostart_pids)) - continue; - lim = &p[autostart_len]; + ) { + pid_t *p, *lim; + waitpid(in.si_pid, NULL, 0); + if (in.si_pid == child_pid) + child_pid = -1; + if (!(p = autostart_pids)) + continue; + lim = &p[autostart_len]; - for (; p < lim; p++) { - if (*p == in.si_pid) { - *p = -1; - break; - } - } - } + for (; p < lim; p++) { + if (*p == in.si_pid) { + *p = -1; + break; + } + } + } } -void //17 -spawn(const Arg *arg) -{ - if (fork() == 0) { - dup2(STDERR_FILENO, STDOUT_FILENO); - setsid(); - execvp(((char **)arg->v)[0], (char **)arg->v); - die("dwl: execvp %s failed:", ((char **)arg->v)[0]); - } +void // 17 +spawn(const Arg *arg) { + if (fork() == 0) { + dup2(STDERR_FILENO, STDOUT_FILENO); + setsid(); + execvp(((char **)arg->v)[0], (char **)arg->v); + die("dwl: execvp %s failed:", ((char **)arg->v)[0]); + } } +void startdrag(struct wl_listener *listener, void *data) { + struct wlr_drag *drag = data; + if (!drag->icon) + return; -void -startdrag(struct wl_listener *listener, void *data) -{ - struct wlr_drag *drag = data; - if (!drag->icon) - return; - - drag->icon->data = &wlr_scene_drag_icon_create(drag_icon, drag->icon)->node; - LISTEN_STATIC(&drag->icon->events.destroy, destroydragicon); + drag->icon->data = &wlr_scene_drag_icon_create(drag_icon, drag->icon)->node; + LISTEN_STATIC(&drag->icon->events.destroy, destroydragicon); } - void tag_client(const Arg *arg, Client *target_client) { - Client *fc; - if (target_client && arg->ui & TAGMASK) { - target_client->tags = arg->ui & TAGMASK; - wl_list_for_each(fc, &clients, link){ - if (fc && fc != target_client && target_client->tags & fc->tags && ISFULLSCREEN(fc) && !target_client->isfloating ) { - clear_fullscreen_flag(fc); - } - } - view(&(Arg){.ui = arg->ui},false); + Client *fc; + if (target_client && arg->ui & TAGMASK) { + target_client->tags = arg->ui & TAGMASK; + wl_list_for_each(fc, &clients, link) { + if (fc && fc != target_client && target_client->tags & fc->tags && + ISFULLSCREEN(fc) && !target_client->isfloating) { + clear_fullscreen_flag(fc); + } + } + view(&(Arg){.ui = arg->ui}, false); - } else{ - view(arg,false); - } + } else { + view(arg, false); + } - focusclient(target_client,1); - printstatus(); + focusclient(target_client, 1); + printstatus(); } -void -tag(const Arg *arg) { - Client *target_client = selmon->sel; - tag_client(arg,target_client); +void tag(const Arg *arg) { + Client *target_client = selmon->sel; + tag_client(arg, target_client); } - -void -tagmon(const Arg *arg) -{ - Client *c = focustop(selmon); - if (c) { - setmon(c, dirtomon(arg->i), 0); - reset_foreign_tolevel(c); - selmon = c->mon; - c->geom.width = (int)(c->geom.width * selmon->m.width/c->mon->m.width); - c->geom.height = (int)(c->geom.height * selmon->m.height/c->mon->m.height); - //重新计算居中的坐标 - if(c->isfloating) { - c->geom = setclient_coordinate_center(c->geom); - resize(c,c->geom,0); - } - warp_cursor_to_selmon(c->mon); - focusclient(c,1); - } - +void tagmon(const Arg *arg) { + Client *c = focustop(selmon); + if (c) { + setmon(c, dirtomon(arg->i), 0); + reset_foreign_tolevel(c); + selmon = c->mon; + c->geom.width = (int)(c->geom.width * selmon->m.width / c->mon->m.width); + c->geom.height = + (int)(c->geom.height * selmon->m.height / c->mon->m.height); + // 重新计算居中的坐标 + if (c->isfloating) { + c->geom = setclient_coordinate_center(c->geom); + resize(c, c->geom, 0); + } + warp_cursor_to_selmon(c->mon); + focusclient(c, 1); + } } -void -overview(Monitor *m, unsigned int gappo, unsigned int gappi) { - grid(m, overviewgappo, overviewgappi); +void overview(Monitor *m, unsigned int gappo, unsigned int gappi) { + grid(m, overviewgappo, overviewgappi); } // 网格布局窗口大小和位置计算 @@ -4580,29 +4523,33 @@ void grid(Monitor *m, unsigned int gappo, unsigned int gappi) { Client *c; Client *tempClients[100]; n = 0; - wl_list_for_each(c, &clients, link) - if (VISIBLEON(c, c->mon) && !c->iskilling && !c->animation.tagouting && c->mon == selmon){ - tempClients[n] = c; - n++; - } + wl_list_for_each(c, &clients, + link) if (VISIBLEON(c, c->mon) && !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]; cw = (m->w.width - 2 * gappo) * 0.7; - ch = (m->w.height- 2 * gappo) * 0.8; - resizeclient(c, m->w.x + (m->m.width - cw) / 2, m->w.y + (m->w.height- ch) / 2, - cw - 2 * c->bw, ch - 2 * c->bw, 0); + ch = (m->w.height - 2 * gappo) * 0.8; + resizeclient(c, m->w.x + (m->m.width - cw) / 2, + m->w.y + (m->w.height - ch) / 2, cw - 2 * c->bw, + ch - 2 * c->bw, 0); return; } if (n == 2) { cw = (m->w.width - 2 * gappo - gappi) / 2; - ch = (m->w.height- 2 * gappo) * 0.65; - resizeclient(tempClients[1], m->m.x + cw + gappo + gappi, m->m.y + (m->m.height - ch) / 2 + gappo, - cw - 2 * tempClients[1]->bw, ch - 2 * tempClients[1]->bw, 0); - resizeclient(tempClients[0], m->m.x + gappo, m->m.y + (m->m.height - ch) / 2 + gappo, - cw - 2 * tempClients[0]->bw, ch - 2 * tempClients[0]->bw, 0); + ch = (m->w.height - 2 * gappo) * 0.65; + resizeclient(tempClients[1], m->m.x + cw + gappo + gappi, + m->m.y + (m->m.height - ch) / 2 + gappo, + cw - 2 * tempClients[1]->bw, ch - 2 * tempClients[1]->bw, 0); + resizeclient(tempClients[0], m->m.x + gappo, + m->m.y + (m->m.height - ch) / 2 + gappo, + cw - 2 * tempClients[0]->bw, ch - 2 * tempClients[0]->bw, 0); return; } @@ -4611,13 +4558,13 @@ void grid(Monitor *m, unsigned int gappo, unsigned int gappi) { if (cols * cols >= n) break; rows = (cols && (cols - 1) * cols >= n) ? cols - 1 : cols; - ch = (m->w.height- 2 * gappo - (rows - 1) * gappi) / rows; + ch = (m->w.height - 2 * gappo - (rows - 1) * gappi) / rows; cw = (m->w.width - 2 * gappo - (cols - 1) * gappi) / cols; overcols = n % cols; if (overcols) dx = (m->w.width - overcols * cw - (overcols - 1) * gappi) / 2 - gappo; - for (i = 0, c = tempClients[0]; c; c = tempClients[i+1], i++) { + for (i = 0, c = tempClients[0]; c; c = tempClients[i + 1], i++) { cx = m->w.x + (i % cols) * (cw + gappi); cy = m->w.y + (i / cols) * (ch + gappi); if (overcols && i >= n - overcols) { @@ -4630,8 +4577,9 @@ void grid(Monitor *m, unsigned int gappo, unsigned int gappi) { // 目标窗口有其他窗口和它同个tag就返回0 unsigned int want_restore_fullscreen(Client *target_client) { Client *c = NULL; - wl_list_for_each(c, &clients, link){ - if (c && c != target_client && c->tags == target_client->tags && c == selmon->sel) { + wl_list_for_each(c, &clients, link) { + if (c && c != target_client && c->tags == target_client->tags && + c == selmon->sel) { return 0; } } @@ -4659,7 +4607,7 @@ void overview_backup(Client *c) { // PropModeReplace, (unsigned char *)0, 0); // } c->isfullscreen = 0; // 清除窗口全屏标志 - c->isfakefullscreen = 0; + c->isfakefullscreen = 0; } c->bw = borderpx; // 恢复非全屏的border } @@ -4673,639 +4621,631 @@ void overview_restore(Client *c, const Arg *arg) { c->overview_isfullscreenbak = 0; c->overview_isfakefullscreenbak = 0; c->bw = c->overview_backup_bw; - c->is_restoring_from_ov = (arg->ui & c->tags) == 0 ? true: false; + c->is_restoring_from_ov = (arg->ui & c->tags) == 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) { - 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; - client_set_fullscreen(c,false); - } + 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) { + 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; + client_set_fullscreen(c, false); + } } else { - resizeclient(c, c->overview_backup_x, c->overview_backup_y, c->overview_backup_w, - c->overview_backup_h, 0); + resizeclient(c, c->overview_backup_x, c->overview_backup_y, + c->overview_backup_w, c->overview_backup_h, 0); } - if(c->bw == 0 && !c->isnoborder && !c->isfullscreen) { //如果是在ov模式中创建的窗口,没有bw记录 - c->bw = borderpx; + if (c->bw == 0 && !c->isnoborder && + !c->isfullscreen) { // 如果是在ov模式中创建的窗口,没有bw记录 + c->bw = borderpx; } - } - // 显示所有tag 或 跳转到聚焦窗口的tag void toggleoverview(const Arg *arg) { - Client *c; - selmon->isoverview ^= 1; - unsigned int target; - unsigned int visible_client_number = 0; + Client *c; + selmon->isoverview ^= 1; + unsigned int target; + unsigned int visible_client_number = 0; - if(selmon->isoverview){ - wl_list_for_each(c, &clients, link) - if (c && c->mon == selmon && !c->isminied){ - visible_client_number++; - } - if(visible_client_number > 0) { - target = ~0; - } else { - selmon->isoverview ^= 1; - return; - } - }else if(!selmon->isoverview && selmon->sel) { - target = get_tags_first_tag(selmon->sel->tags); - } else if (!selmon->isoverview && !selmon->sel) { - target = (1 << (selmon->pertag->prevtag-1)); - view(&(Arg){.ui = target},false); - return; - } + if (selmon->isoverview) { + wl_list_for_each(c, &clients, + link) if (c && c->mon == selmon && !c->isminied) { + visible_client_number++; + } + if (visible_client_number > 0) { + target = ~0; + } else { + selmon->isoverview ^= 1; + return; + } + } else if (!selmon->isoverview && selmon->sel) { + target = get_tags_first_tag(selmon->sel->tags); + } else if (!selmon->isoverview && !selmon->sel) { + target = (1 << (selmon->pertag->prevtag - 1)); + view(&(Arg){.ui = target}, false); + return; + } - // 正常视图到overview,退出所有窗口的浮动和全屏状态参与平铺, - // overview到正常视图,还原之前退出的浮动和全屏窗口状态 - if (selmon->isoverview) { - wl_list_for_each(c, &clients, link){ - if(c) - overview_backup(c); - } - } else { - wl_list_for_each(c, &clients, link){ - if(c && (c != selmon->sel || c->overview_isfloatingbak || c->overview_isfullscreenbak || c->overview_isfakefullscreenbak) && !c->iskilling && client_surface(c)->mapped) - overview_restore(c, &(Arg){.ui = target}); - } - } - - view(&(Arg){.ui = target},false); + // 正常视图到overview,退出所有窗口的浮动和全屏状态参与平铺, + // overview到正常视图,还原之前退出的浮动和全屏窗口状态 + if (selmon->isoverview) { + wl_list_for_each(c, &clients, link) { + if (c) + overview_backup(c); + } + } else { + wl_list_for_each(c, &clients, link) { + if (c && + (c != selmon->sel || c->overview_isfloatingbak || + c->overview_isfullscreenbak || c->overview_isfakefullscreenbak) && + !c->iskilling && client_surface(c)->mapped) + overview_restore(c, &(Arg){.ui = target}); + } + } + view(&(Arg){.ui = target}, false); } -void -tile(Monitor *m,unsigned int gappo, unsigned int uappi) -{ - unsigned int i, n = 0, h, r, oe = enablegaps, ie = enablegaps, mw, my, ty; - Client *c; +void tile(Monitor *m, unsigned int gappo, unsigned int uappi) { + unsigned int i, n = 0, h, r, oe = enablegaps, ie = enablegaps, mw, my, ty; + Client *c; - wl_list_for_each(c, &clients, link) - if (VISIBLEON(c, m) && !c->animation.tagouting && !c->iskilling && !c->isfloating && !c->isfullscreen && !c->isfakefullscreen) - n++; - if (n == 0) - return; + wl_list_for_each(c, &clients, + link) if (VISIBLEON(c, m) && !c->animation.tagouting && + !c->iskilling && !c->isfloating && + !c->isfullscreen && !c->isfakefullscreen) n++; + if (n == 0) + return; - if (smartgaps == n) { - oe = 0; // outer gaps disabled - } + if (smartgaps == n) { + oe = 0; // outer gaps disabled + } - if (n > selmon->pertag->nmasters[selmon->pertag->curtag]) - mw = selmon->pertag->nmasters[selmon->pertag->curtag] ? (m->w.width + m->gappiv*ie) * selmon->pertag->mfacts[selmon->pertag->curtag] : 0; - else - mw = m->w.width - 2*m->gappov*oe + m->gappiv*ie; - i = 0; - 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 ) - continue; - if (i < selmon->pertag->nmasters[selmon->pertag->curtag]) { - r = MIN(n, selmon->pertag->nmasters[selmon->pertag->curtag]) - i; - h = (m->w.height - my - m->gappoh*oe - m->gappih*ie * (r - 1)) / r; - resize(c, (struct wlr_box){.x = m->w.x + m->gappov*oe, .y = m->w.y + my, - .width = mw - m->gappiv*ie, .height = h}, 0); - my += c->geom.height + m->gappih*ie; - } else { - r = n - i; - h = (m->w.height - ty - m->gappoh*oe - m->gappih*ie * (r - 1)) / r; - resize(c, (struct wlr_box){.x = m->w.x + mw + m->gappov*oe, .y = m->w.y + ty, - .width = m->w.width - mw - 2*m->gappov*oe, .height = h}, 0); - ty += c->geom.height + m->gappih*ie; - } - i++; - } + if (n > selmon->pertag->nmasters[selmon->pertag->curtag]) + mw = selmon->pertag->nmasters[selmon->pertag->curtag] + ? (m->w.width + m->gappiv * ie) * + selmon->pertag->mfacts[selmon->pertag->curtag] + : 0; + else + mw = m->w.width - 2 * m->gappov * oe + m->gappiv * ie; + i = 0; + 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) + continue; + if (i < selmon->pertag->nmasters[selmon->pertag->curtag]) { + r = MIN(n, selmon->pertag->nmasters[selmon->pertag->curtag]) - i; + h = (m->w.height - my - m->gappoh * oe - m->gappih * ie * (r - 1)) / r; + resize(c, + (struct wlr_box){.x = m->w.x + m->gappov * oe, + .y = m->w.y + my, + .width = mw - m->gappiv * ie, + .height = h}, + 0); + my += c->geom.height + m->gappih * ie; + } else { + r = n - i; + h = (m->w.height - ty - m->gappoh * oe - m->gappih * ie * (r - 1)) / r; + resize(c, + (struct wlr_box){.x = m->w.x + mw + m->gappov * oe, + .y = m->w.y + ty, + .width = m->w.width - mw - 2 * m->gappov * oe, + .height = h}, + 0); + ty += c->geom.height + m->gappih * ie; + } + i++; + } } +void togglefloating(const Arg *arg) { + Client *sel = focustop(selmon); -void -togglefloating(const Arg *arg) -{ - Client *sel = focustop(selmon); + if (!sel) + return; - if(!sel) - return; - - if (sel->isfullscreen || sel->isfakefullscreen) { - sel->isfullscreen = 0; // 清除窗口全屏标志 - sel->isfakefullscreen = 0; - sel->bw = borderpx; // 恢复非全屏的border - } - /* return if fullscreen */ - setfloating(sel, !sel->isfloating); - setborder_color(sel); + if (sel->isfullscreen || sel->isfakefullscreen) { + sel->isfullscreen = 0; // 清除窗口全屏标志 + sel->isfakefullscreen = 0; + sel->bw = borderpx; // 恢复非全屏的border + } + /* return if fullscreen */ + setfloating(sel, !sel->isfloating); + setborder_color(sel); } -void -togglefullscreen(const Arg *arg) -{ - Client *sel = focustop(selmon); - if(!sel) - return; +void togglefullscreen(const Arg *arg) { + Client *sel = focustop(selmon); + if (!sel) + return; - // if(sel->isfloating) - // setfloating(sel, 0); + // if(sel->isfloating) + // setfloating(sel, 0); - if (sel->isfullscreen || sel->isfakefullscreen) - setfullscreen(sel, 0); - else - setfullscreen(sel, 1); + if (sel->isfullscreen || sel->isfakefullscreen) + setfullscreen(sel, 0); + else + setfullscreen(sel, 1); - sel->is_scratchpad_show = 0; - sel->is_in_scratchpad = 0; + sel->is_scratchpad_show = 0; + sel->is_in_scratchpad = 0; } -void -togglefakefullscreen(const Arg *arg) -{ - Client *sel = focustop(selmon); - if(!sel) - return; +void togglefakefullscreen(const Arg *arg) { + Client *sel = focustop(selmon); + if (!sel) + return; - // if(sel->isfloating) - // setfloating(sel, 0); + // if(sel->isfloating) + // setfloating(sel, 0); - if (sel->isfullscreen || sel->isfakefullscreen) - setfakefullscreen(sel, 0); - else - setfakefullscreen(sel, 1); + if (sel->isfullscreen || sel->isfakefullscreen) + setfakefullscreen(sel, 0); + else + setfakefullscreen(sel, 1); - sel->is_scratchpad_show = 0; - sel->is_in_scratchpad = 0; + sel->is_scratchpad_show = 0; + sel->is_in_scratchpad = 0; } -void -togglegaps(const Arg *arg) -{ - enablegaps ^= 1; - arrange(selmon,false); +void togglegaps(const Arg *arg) { + enablegaps ^= 1; + arrange(selmon, false); } -void -toggletag(const Arg *arg) -{ - unsigned int newtags; - Client *sel = focustop(selmon); - if (!sel) - return; - newtags = sel->tags ^ (arg->ui & TAGMASK); - if (newtags) { - sel->tags = newtags; - focusclient(focustop(selmon), 1); - arrange(selmon,true); - } - printstatus(); +void toggletag(const Arg *arg) { + unsigned int newtags; + Client *sel = focustop(selmon); + if (!sel) + return; + newtags = sel->tags ^ (arg->ui & TAGMASK); + if (newtags) { + sel->tags = newtags; + focusclient(focustop(selmon), 1); + arrange(selmon, true); + } + printstatus(); } -void -toggleview(const Arg *arg) -{ - unsigned int newtagset = selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0; +void toggleview(const Arg *arg) { + unsigned int newtagset = + selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0; - if (newtagset) { - selmon->tagset[selmon->seltags] = newtagset; - focusclient(focustop(selmon), 1); - arrange(selmon,false); - } - printstatus(); + if (newtagset) { + selmon->tagset[selmon->seltags] = newtagset; + focusclient(focustop(selmon), 1); + arrange(selmon, false); + } + printstatus(); } void // 0.5 -unlocksession(struct wl_listener *listener, void *data) -{ - SessionLock *lock = wl_container_of(listener, lock, unlock); - destroylock(lock, 1); +unlocksession(struct wl_listener *listener, void *data) { + SessionLock *lock = wl_container_of(listener, lock, unlock); + destroylock(lock, 1); } void // 0.5 -unmaplayersurfacenotify(struct wl_listener *listener, void *data) -{ - LayerSurface *l = wl_container_of(listener, l, unmap); +unmaplayersurfacenotify(struct wl_listener *listener, void *data) { + LayerSurface *l = wl_container_of(listener, l, unmap); - l->mapped = 0; - wlr_scene_node_set_enabled(&l->scene->node, 0); - if (l == exclusive_focus) - exclusive_focus = NULL; - if (l->layer_surface->output && (l->mon = l->layer_surface->output->data)) - arrangelayers(l->mon); - if (l->layer_surface->surface == seat->keyboard_state.focused_surface) - focusclient(focustop(selmon), 1); - motionnotify(0, NULL, 0, 0, 0, 0); + l->mapped = 0; + wlr_scene_node_set_enabled(&l->scene->node, 0); + if (l == exclusive_focus) + exclusive_focus = NULL; + if (l->layer_surface->output && (l->mon = l->layer_surface->output->data)) + arrangelayers(l->mon); + if (l->layer_surface->surface == seat->keyboard_state.focused_surface) + focusclient(focustop(selmon), 1); + motionnotify(0, NULL, 0, 0, 0, 0); } -void -unmapnotify(struct wl_listener *listener, void *data) -{ - /* Called when the surface is unmapped, and should no longer be shown. */ - Client *c = wl_container_of(listener, c, unmap); +void unmapnotify(struct wl_listener *listener, void *data) { + /* Called when the surface is unmapped, and should no longer be shown. */ + Client *c = wl_container_of(listener, c, unmap); - if (c == grabc) { - cursor_mode = CurNormal; - grabc = NULL; - } + if (c == grabc) { + cursor_mode = CurNormal; + grabc = NULL; + } - if (c == selmon->sel) { - selmon->sel = NULL; - Client *nextfocus = focustop(selmon); + if (c == selmon->sel) { + selmon->sel = NULL; + Client *nextfocus = focustop(selmon); - if(nextfocus) { - focusclient(nextfocus,0); - } + if (nextfocus) { + focusclient(nextfocus, 0); + } - if(!nextfocus && selmon->isoverview){ - Arg arg = {0}; - toggleoverview(&arg); - } - } + if (!nextfocus && selmon->isoverview) { + Arg arg = {0}; + toggleoverview(&arg); + } + } - if (client_is_unmanaged(c)) { - if (c == exclusive_focus) - exclusive_focus = NULL; - if (client_surface(c) == seat->keyboard_state.focused_surface) - focusclient(focustop(selmon), 1); - } else { - wl_list_remove(&c->link); - setmon(c, NULL, 0); - wl_list_remove(&c->flink); - } + if (client_is_unmanaged(c)) { + if (c == exclusive_focus) + exclusive_focus = NULL; + if (client_surface(c) == seat->keyboard_state.focused_surface) + focusclient(focustop(selmon), 1); + } else { + wl_list_remove(&c->link); + setmon(c, NULL, 0); + wl_list_remove(&c->flink); + } - if(c->foreign_toplevel){ - wlr_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel); - c->foreign_toplevel = NULL; - } + if (c->foreign_toplevel) { + wlr_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel); + c->foreign_toplevel = NULL; + } - wlr_scene_node_destroy(&c->scene->node); - printstatus(); - motionnotify(0, NULL, 0, 0, 0, 0); + wlr_scene_node_destroy(&c->scene->node); + printstatus(); + motionnotify(0, NULL, 0, 0, 0, 0); } -void //0.5 -updatemons(struct wl_listener *listener, void *data) -{ - /* - * Called whenever the output layout changes: adding or removing a - * monitor, changing an output's mode or position, etc. This is where - * the change officially happens and we update geometry, window - * positions, focus, and the stored configuration in wlroots' - * output-manager implementation. - */ - struct wlr_output_configuration_v1 *config - = wlr_output_configuration_v1_create(); - Client *c; - struct wlr_output_configuration_head_v1 *config_head; - Monitor *m; +void // 0.5 +updatemons(struct wl_listener *listener, void *data) { + /* + * Called whenever the output layout changes: adding or removing a + * monitor, changing an output's mode or position, etc. This is where + * the change officially happens and we update geometry, window + * positions, focus, and the stored configuration in wlroots' + * output-manager implementation. + */ + struct wlr_output_configuration_v1 *config = + wlr_output_configuration_v1_create(); + Client *c; + struct wlr_output_configuration_head_v1 *config_head; + Monitor *m; - /* First remove from the layout the disabled monitors */ - wl_list_for_each(m, &mons, link) { - if (m->wlr_output->enabled) - continue; - config_head = wlr_output_configuration_head_v1_create(config, m->wlr_output); - config_head->state.enabled = 0; - /* Remove this output from the layout to avoid cursor enter inside it */ - wlr_output_layout_remove(output_layout, m->wlr_output); - closemon(m); - m->m = m->w = (struct wlr_box){0}; - } - /* Insert outputs that need to */ - wl_list_for_each(m, &mons, link) { - if (m->wlr_output->enabled - && !wlr_output_layout_get(output_layout, m->wlr_output)) - wlr_output_layout_add_auto(output_layout, m->wlr_output); - } + /* First remove from the layout the disabled monitors */ + wl_list_for_each(m, &mons, link) { + if (m->wlr_output->enabled) + continue; + config_head = + wlr_output_configuration_head_v1_create(config, m->wlr_output); + config_head->state.enabled = 0; + /* Remove this output from the layout to avoid cursor enter inside it */ + wlr_output_layout_remove(output_layout, m->wlr_output); + closemon(m); + m->m = m->w = (struct wlr_box){0}; + } + /* Insert outputs that need to */ + wl_list_for_each(m, &mons, link) { + if (m->wlr_output->enabled && + !wlr_output_layout_get(output_layout, m->wlr_output)) + wlr_output_layout_add_auto(output_layout, m->wlr_output); + } - /* Now that we update the output layout we can get its box */ - wlr_output_layout_get_box(output_layout, NULL, &sgeom); + /* Now that we update the output layout we can get its box */ + wlr_output_layout_get_box(output_layout, NULL, &sgeom); - /* Make sure the clients are hidden when dwl is locked */ - wlr_scene_node_set_position(&locked_bg->node, sgeom.x, sgeom.y); - wlr_scene_rect_set_size(locked_bg, sgeom.width, sgeom.height); + /* Make sure the clients are hidden when dwl is locked */ + wlr_scene_node_set_position(&locked_bg->node, sgeom.x, sgeom.y); + wlr_scene_rect_set_size(locked_bg, sgeom.width, sgeom.height); - wl_list_for_each(m, &mons, link) { - if (!m->wlr_output->enabled) - continue; - config_head = wlr_output_configuration_head_v1_create(config, m->wlr_output); + wl_list_for_each(m, &mons, link) { + if (!m->wlr_output->enabled) + continue; + config_head = + wlr_output_configuration_head_v1_create(config, m->wlr_output); - /* Get the effective monitor geometry to use for surfaces */ - wlr_output_layout_get_box(output_layout, m->wlr_output, &m->m); - m->w = m->m; - wlr_scene_output_set_position(m->scene_output, m->m.x, m->m.y); + /* Get the effective monitor geometry to use for surfaces */ + wlr_output_layout_get_box(output_layout, m->wlr_output, &m->m); + m->w = m->m; + wlr_scene_output_set_position(m->scene_output, m->m.x, m->m.y); - // wlr_scene_node_set_position(&m->fullscreen_bg->node, m->m.x, m->m.y); - // wlr_scene_rect_set_size(m->fullscreen_bg, m->m.width, m->m.height); + // wlr_scene_node_set_position(&m->fullscreen_bg->node, m->m.x, m->m.y); + // wlr_scene_rect_set_size(m->fullscreen_bg, m->m.width, m->m.height); - if (m->lock_surface) { - struct wlr_scene_tree *scene_tree = m->lock_surface->surface->data; - wlr_scene_node_set_position(&scene_tree->node, m->m.x, m->m.y); - wlr_session_lock_surface_v1_configure(m->lock_surface, m->m.width, m->m.height); - } + if (m->lock_surface) { + struct wlr_scene_tree *scene_tree = m->lock_surface->surface->data; + wlr_scene_node_set_position(&scene_tree->node, m->m.x, m->m.y); + wlr_session_lock_surface_v1_configure(m->lock_surface, m->m.width, + m->m.height); + } - /* Calculate the effective monitor geometry to use for clients */ - arrangelayers(m); - /* Don't move clients to the left output when plugging monitors */ - arrange(m,false); - /* make sure fullscreen clients have the right size */ - if ((c = focustop(m)) && c->isfullscreen) - resize(c, m->m, 0); + /* Calculate the effective monitor geometry to use for clients */ + arrangelayers(m); + /* Don't move clients to the left output when plugging monitors */ + arrange(m, false); + /* make sure fullscreen clients have the right size */ + if ((c = focustop(m)) && c->isfullscreen) + resize(c, m->m, 0); - /* Try to re-set the gamma LUT when updating monitors, - * it's only really needed when enabling a disabled output, but meh. */ - m->gamma_lut_changed = 1; + /* Try to re-set the gamma LUT when updating monitors, + * it's only really needed when enabling a disabled output, but meh. */ + m->gamma_lut_changed = 1; - config_head->state.x = m->m.x; - config_head->state.y = m->m.y; - if (!selmon) { - selmon = m; - } - } + config_head->state.x = m->m.x; + config_head->state.y = m->m.y; + if (!selmon) { + selmon = m; + } + } - if (selmon && selmon->wlr_output->enabled) { - wl_list_for_each(c, &clients, link) { - if (!c->mon && client_surface(c)->mapped) { - setmon(c, selmon, c->tags); - reset_foreign_tolevel(c); - } - } - focusclient(focustop(selmon), 1); - if (selmon->lock_surface) { - client_notify_enter(selmon->lock_surface->surface, - wlr_seat_get_keyboard(seat)); - client_activate_surface(selmon->lock_surface->surface, 1); - } - } + if (selmon && selmon->wlr_output->enabled) { + wl_list_for_each(c, &clients, link) { + if (!c->mon && client_surface(c)->mapped) { + setmon(c, selmon, c->tags); + reset_foreign_tolevel(c); + } + } + focusclient(focustop(selmon), 1); + if (selmon->lock_surface) { + client_notify_enter(selmon->lock_surface->surface, + wlr_seat_get_keyboard(seat)); + client_activate_surface(selmon->lock_surface->surface, 1); + } + } - /* FIXME: figure out why the cursor image is at 0,0 after turning all - * the monitors on. - * Move the cursor image where it used to be. It does not generate a - * wl_pointer.motion event for the clients, it's only the image what it's - * at the wrong position after all. */ - wlr_cursor_move(cursor, NULL, 0, 0); + /* FIXME: figure out why the cursor image is at 0,0 after turning all + * the monitors on. + * Move the cursor image where it used to be. It does not generate a + * wl_pointer.motion event for the clients, it's only the image what it's + * at the wrong position after all. */ + wlr_cursor_move(cursor, NULL, 0, 0); - wlr_output_manager_v1_set_configuration(output_mgr, config); + wlr_output_manager_v1_set_configuration(output_mgr, config); } -void -updatetitle(struct wl_listener *listener, void *data) -{ - Client *c = wl_container_of(listener, c, set_title); - const char *title; - title = client_get_title(c) ; - if(title && c->foreign_toplevel) - wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel,title); - if (c == focustop(c->mon)) - printstatus(); - +void updatetitle(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, set_title); + const char *title; + title = client_get_title(c); + if (title && c->foreign_toplevel) + wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel, title); + if (c == focustop(c->mon)) + printstatus(); } -void //17 fix to 0.5 -urgent(struct wl_listener *listener, void *data) -{ - struct wlr_xdg_activation_v1_request_activate_event *event = data; - Client *c = NULL; - toplevel_from_wlr_surface(event->surface, &c, NULL); +void // 17 fix to 0.5 +urgent(struct wl_listener *listener, void *data) { + struct wlr_xdg_activation_v1_request_activate_event *event = data; + Client *c = NULL; + toplevel_from_wlr_surface(event->surface, &c, NULL); - if (!c || !c->foreign_toplevel) - return; + if (!c || !c->foreign_toplevel) + return; - if (focus_on_activate && c != selmon->sel) { - view(&(Arg){.ui = c->tags},true); - focusclient(c,1); - } else if(c != focustop(selmon)) { - if (client_surface(c)->mapped) - client_set_border_color(c, urgentcolor); - c->isurgent = 1; - printstatus(); - } + if (focus_on_activate && c != selmon->sel) { + view(&(Arg){.ui = c->tags}, true); + focusclient(c, 1); + } else if (c != focustop(selmon)) { + if (client_surface(c)->mapped) + client_set_border_color(c, urgentcolor); + c->isurgent = 1; + printstatus(); + } } -void bind_to_view(const Arg *arg) { - view(arg,true); +void bind_to_view(const Arg *arg) { view(arg, true); } + +void view(const Arg *arg, bool want_animation) { + size_t i, tmptag; + + if (!selmon || (arg->ui != ~0 && selmon->isoverview)) { + return; + } + + if ((selmon->tagset[selmon->seltags] & arg->ui & TAGMASK) != 0) { + want_animation = false; + } + + selmon->seltags ^= 1; /* toggle sel tagset */ + if (arg->ui & TAGMASK) { + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; + selmon->pertag->prevtag = selmon->pertag->curtag; + + if (arg->ui == ~0) + selmon->pertag->curtag = 0; + else { + for (i = 0; !(arg->ui & 1 << i); i++) + ; + selmon->pertag->curtag = i + 1; + } + } else { + tmptag = selmon->pertag->prevtag; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = tmptag; + } + + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; + selmon->lt[selmon->sellt] = + selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; + selmon->lt[selmon->sellt ^ 1] = + selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt ^ 1]; + + focusclient(focustop(selmon), 1); + arrange(selmon, want_animation); + printstatus(); } -void -view(const Arg *arg,bool want_animation) -{ - size_t i, tmptag; +void viewtoleft(const Arg *arg) { + size_t tmptag; + unsigned int target = selmon->tagset[selmon->seltags]; - if(!selmon || (arg->ui != ~0 && selmon->isoverview)){ - return; - } + if (selmon->isoverview || selmon->pertag->curtag == 0) { + return; + } - if ((selmon->tagset[selmon->seltags] & arg->ui & TAGMASK) != 0) { - want_animation = false; - } - - selmon->seltags ^= 1; /* toggle sel tagset */ - if (arg->ui & TAGMASK) { - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; - selmon->pertag->prevtag = selmon->pertag->curtag; + target >>= 1; - if (arg->ui == ~0) - selmon->pertag->curtag = 0; - else { - for (i = 0; !(arg->ui & 1 << i); i++) ; - selmon->pertag->curtag = i + 1; - } - } else { - tmptag = selmon->pertag->prevtag; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = tmptag; - } + if (target == 0) { + return; + } - selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; - selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; - selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; + if (!selmon || (target) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ + if (target) { + selmon->tagset[selmon->seltags] = target; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = selmon->pertag->curtag - 1; + } else { + tmptag = selmon->pertag->prevtag; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = tmptag; + } - focusclient(focustop(selmon), 1); - arrange(selmon,want_animation); - printstatus(); + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; + selmon->lt[selmon->sellt] = + selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; + selmon->lt[selmon->sellt ^ 1] = + selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt ^ 1]; + + focusclient(focustop(selmon), 1); + arrange(selmon, true); + printstatus(); } +void viewtoright_have_client(const Arg *arg) { + size_t tmptag; + Client *c; + unsigned int found = 0; + unsigned int n = 1; + unsigned int target = selmon->tagset[selmon->seltags]; -void -viewtoleft(const Arg *arg) -{ - size_t tmptag; - unsigned int target = selmon->tagset[selmon->seltags]; + if (selmon->isoverview || selmon->pertag->curtag == 0) { + return; + } - if(selmon->isoverview || selmon->pertag->curtag == 0){ - return; - } + for (target <<= 1; target & TAGMASK; target <<= 1, n++) { + wl_list_for_each(c, &clients, link) { + if (target & c->tags) { + found = 1; + break; + } + } + if (found) { + break; + } + } - target >>= 1; + if (!(target & TAGMASK)) { + return; + } - if(target == 0){ - return; - } + if (!selmon || (target) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ + if (target) { + selmon->tagset[selmon->seltags] = target; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = selmon->pertag->curtag + n; + } else { + tmptag = selmon->pertag->prevtag; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = tmptag; + } - if (!selmon || (target) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ - if (target) { - selmon->tagset[selmon->seltags] = target; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = selmon->pertag->curtag - 1; - } else { - tmptag = selmon->pertag->prevtag; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = tmptag; - } + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; + selmon->lt[selmon->sellt] = + selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; + selmon->lt[selmon->sellt ^ 1] = + selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt ^ 1]; - selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; - selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; - selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; - - focusclient(focustop(selmon), 1); - arrange(selmon,true); - printstatus(); + focusclient(focustop(selmon), 1); + arrange(selmon, true); + printstatus(); } -void -viewtoright_have_client(const Arg *arg) -{ - size_t tmptag; - Client *c; - unsigned int found = 0; - unsigned int n = 1; - unsigned int target = selmon->tagset[selmon->seltags]; +void viewtoright(const Arg *arg) { + if (selmon->isoverview || selmon->pertag->curtag == 0) { + return; + } + size_t tmptag; + unsigned int target = selmon->tagset[selmon->seltags]; + target <<= 1; - if(selmon->isoverview || selmon->pertag->curtag == 0){ - return; - } + if (!selmon || (target) == selmon->tagset[selmon->seltags]) + return; + if (!(target & TAGMASK)) { + return; + } + selmon->seltags ^= 1; /* toggle sel tagset */ + if (target) { + selmon->tagset[selmon->seltags] = target; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = selmon->pertag->curtag + 1; + } else { + tmptag = selmon->pertag->prevtag; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = tmptag; + } - for(target <<= 1;target & TAGMASK;target <<= 1,n++){ - wl_list_for_each(c, &clients, link){ - if(target & c->tags){ - found = 1; - break; - } - } - if(found){ - break; - } - } + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; + selmon->lt[selmon->sellt] = + selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; + selmon->lt[selmon->sellt ^ 1] = + selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt ^ 1]; - if(!(target & TAGMASK)){ - return; - } - - if (!selmon || (target) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ - if (target) { - selmon->tagset[selmon->seltags] = target; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = selmon->pertag->curtag + n; - } else { - tmptag = selmon->pertag->prevtag; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = tmptag; - } - - selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; - selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; - selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; - - focusclient(focustop(selmon), 1); - arrange(selmon,true); - printstatus(); + focusclient(focustop(selmon), 1); + arrange(selmon, true); + printstatus(); } -void -viewtoright(const Arg *arg) -{ - if(selmon->isoverview || selmon->pertag->curtag == 0){ - return; - } - size_t tmptag; - unsigned int target = selmon->tagset[selmon->seltags]; - target <<= 1; +void viewtoleft_have_client(const Arg *arg) { + size_t tmptag; + Client *c; + unsigned int found = 0; + unsigned int n = 1; + unsigned int target = selmon->tagset[selmon->seltags]; - if (!selmon || (target) == selmon->tagset[selmon->seltags]) - return; - if (!(target & TAGMASK)){ - return; - } - selmon->seltags ^= 1; /* toggle sel tagset */ - if (target) { - selmon->tagset[selmon->seltags] = target; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = selmon->pertag->curtag + 1; - } else { - tmptag = selmon->pertag->prevtag; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = tmptag; - } + if (selmon->isoverview || selmon->pertag->curtag == 0) { + return; + } - selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; - selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; - selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; + for (target >>= 1; target > 0; target >>= 1, n++) { + wl_list_for_each(c, &clients, link) { + if (target & c->tags) { + found = 1; + break; + } + } + if (found) { + break; + } + } - focusclient(focustop(selmon), 1); - arrange(selmon,true); - printstatus(); + if (target == 0) { + return; + } + + if (!selmon || (target) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ + if (target) { + selmon->tagset[selmon->seltags] = target; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = selmon->pertag->curtag - n; + } else { + tmptag = selmon->pertag->prevtag; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = tmptag; + } + + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; + selmon->lt[selmon->sellt] = + selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; + selmon->lt[selmon->sellt ^ 1] = + selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt ^ 1]; + + focusclient(focustop(selmon), 1); + arrange(selmon, true); + printstatus(); } -void -viewtoleft_have_client(const Arg *arg) -{ - size_t tmptag; - Client *c; - unsigned int found = 0; - unsigned int n = 1; - unsigned int target = selmon->tagset[selmon->seltags]; - - if(selmon->isoverview || selmon->pertag->curtag == 0){ - return; - } - - for(target >>= 1;target>0;target >>= 1,n++){ - wl_list_for_each(c, &clients, link){ - if(target & c->tags){ - found = 1; - break; - } - } - if(found){ - break; - } - } - - if(target == 0){ - return; - } - - if (!selmon || (target) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ - if (target) { - selmon->tagset[selmon->seltags] = target; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = selmon->pertag->curtag - n; - } else { - tmptag = selmon->pertag->prevtag; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = tmptag; - } - - selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; - selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; - selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; - - focusclient(focustop(selmon), 1); - arrange(selmon,true); - printstatus(); -} - - void tagtoleft(const Arg *arg) { if (selmon->sel != NULL && __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 && @@ -5322,85 +5262,73 @@ void tagtoright(const Arg *arg) { } } - -void -virtualkeyboard(struct wl_listener *listener, void *data) -{ - struct wlr_virtual_keyboard_v1 *keyboard = data; - createkeyboard(&keyboard->keyboard); +void virtualkeyboard(struct wl_listener *listener, void *data) { + struct wlr_virtual_keyboard_v1 *keyboard = data; + createkeyboard(&keyboard->keyboard); } -void -warp_cursor(const Client *c) { - if (cursor->x < c->geom.x || - cursor->x > c->geom.x + c->geom.width || - cursor->y < c->geom.y || - cursor->y > c->geom.y + c->geom.height) - wlr_cursor_warp_closest(cursor, - NULL, - c->geom.x + c->geom.width / 2.0, - c->geom.y + c->geom.height / 2.0); +void warp_cursor(const Client *c) { + if (cursor->x < c->geom.x || cursor->x > c->geom.x + c->geom.width || + cursor->y < c->geom.y || cursor->y > c->geom.y + c->geom.height) + wlr_cursor_warp_closest(cursor, NULL, c->geom.x + c->geom.width / 2.0, + c->geom.y + c->geom.height / 2.0); } -void -warp_cursor_to_selmon(const Monitor *m) { +void warp_cursor_to_selmon(const Monitor *m) { - wlr_cursor_warp_closest(cursor, - NULL, - m->w.x + m->w.width / 2.0, - m->w.y + m->w.height / 2.0); + wlr_cursor_warp_closest(cursor, NULL, m->w.x + m->w.width / 2.0, + m->w.y + m->w.height / 2.0); } -void -virtualpointer(struct wl_listener *listener, void *data) -{ - struct wlr_virtual_pointer_v1_new_pointer_event *event = data; - struct wlr_input_device *device = &event->new_pointer->pointer.base; +void virtualpointer(struct wl_listener *listener, void *data) { + struct wlr_virtual_pointer_v1_new_pointer_event *event = data; + struct wlr_input_device *device = &event->new_pointer->pointer.base; - wlr_cursor_attach_input_device(cursor, device); - if (event->suggested_output) - wlr_cursor_map_input_to_output(cursor, device, event->suggested_output); + wlr_cursor_attach_input_device(cursor, device); + if (event->suggested_output) + wlr_cursor_map_input_to_output(cursor, device, event->suggested_output); } -Monitor * -xytomon(double x, double y) -{ - struct wlr_output *o = wlr_output_layout_output_at(output_layout, x, y); - return o ? o->data : NULL; +Monitor *xytomon(double x, double y) { + struct wlr_output *o = wlr_output_layout_output_at(output_layout, x, y); + return o ? o->data : NULL; } -void -xytonode(double x, double y, struct wlr_surface **psurface, - Client **pc, LayerSurface **pl, double *nx, double *ny) -{ - struct wlr_scene_node *node, *pnode; - struct wlr_surface *surface = NULL; - Client *c = NULL; - LayerSurface *l = NULL; - int layer; +void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc, + LayerSurface **pl, double *nx, double *ny) { + struct wlr_scene_node *node, *pnode; + struct wlr_surface *surface = NULL; + Client *c = NULL; + LayerSurface *l = NULL; + int layer; - for (layer = NUM_LAYERS - 1; !surface && layer >= 0; layer--) { - #ifdef IM - if (layer == LyrIMPopup) continue; - #endif - if (!(node = wlr_scene_node_at(&layers[layer]->node, x, y, nx, ny))) - continue; + for (layer = NUM_LAYERS - 1; !surface && layer >= 0; layer--) { +#ifdef IM + if (layer == LyrIMPopup) + continue; +#endif + if (!(node = wlr_scene_node_at(&layers[layer]->node, x, y, nx, ny))) + continue; - if (node->type == WLR_SCENE_NODE_BUFFER) - surface = wlr_scene_surface_try_from_buffer( - wlr_scene_buffer_from_node(node))->surface; - /* Walk the tree to find a node that knows the client */ - for (pnode = node; pnode && !c; pnode = &pnode->parent->node) - c = pnode->data; - if (c && c->type == LayerShell) { - c = NULL; - l = pnode->data; - } - } + if (node->type == WLR_SCENE_NODE_BUFFER) + surface = + wlr_scene_surface_try_from_buffer(wlr_scene_buffer_from_node(node)) + ->surface; + /* Walk the tree to find a node that knows the client */ + for (pnode = node; pnode && !c; pnode = &pnode->parent->node) + c = pnode->data; + if (c && c->type == LayerShell) { + c = NULL; + l = pnode->data; + } + } - if (psurface) *psurface = surface; - if (pc) *pc = c; - if (pl) *pl = l; + if (psurface) + *psurface = surface; + if (pc) + *pc = c; + if (pl) + *pl = l; } void toggleglobal(const Arg *arg) { @@ -5409,201 +5337,196 @@ void toggleglobal(const Arg *arg) { if (selmon->sel->is_in_scratchpad) { selmon->sel->is_in_scratchpad = 0; selmon->sel->is_scratchpad_show = 0; - } + } selmon->sel->isglobal ^= 1; -// selmon->sel->tags = -// selmon->sel->isglobal ? TAGMASK : selmon->tagset[selmon->seltags]; -// focustop(selmon); + // selmon->sel->tags = + // selmon->sel->isglobal ? TAGMASK : selmon->tagset[selmon->seltags]; + // focustop(selmon); setborder_color(selmon->sel); } -void -zoom(const Arg *arg) -{ - Client *c, *sel = focustop(selmon); +void zoom(const Arg *arg) { + Client *c, *sel = focustop(selmon); - if (!sel || !selmon || !selmon->lt[selmon->sellt]->arrange || sel->isfloating) - return; + if (!sel || !selmon || !selmon->lt[selmon->sellt]->arrange || sel->isfloating) + return; - /* Search for the first tiled window that is not sel, marking sel as - * NULL if we pass it along the way */ - wl_list_for_each(c, &clients, link) - if (VISIBLEON(c, selmon) && !c->isfloating) { - if (c != sel) - break; - sel = NULL; - } + /* Search for the first tiled window that is not sel, marking sel as + * NULL if we pass it along the way */ + wl_list_for_each(c, &clients, + link) if (VISIBLEON(c, selmon) && !c->isfloating) { + if (c != sel) + break; + sel = NULL; + } - /* Return if no other tiled window was found */ - if (&c->link == &clients) - return; + /* Return if no other tiled window was found */ + if (&c->link == &clients) + return; - /* If we passed sel, move c to the front; otherwise, move sel to the - * front */ - if (!sel) - sel = c; - wl_list_remove(&sel->link); - wl_list_insert(&clients, &sel->link); + /* If we passed sel, move c to the front; otherwise, move sel to the + * front */ + if (!sel) + sel = c; + wl_list_remove(&sel->link); + wl_list_insert(&clients, &sel->link); - focusclient(sel, 1); - arrange(selmon,false); + focusclient(sel, 1); + arrange(selmon, false); } #ifdef XWAYLAND -void -activatex11(struct wl_listener *listener, void *data) -{ - Client *c = wl_container_of(listener, c, activate); +void activatex11(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, activate); - /* Only "managed" windows can be activated */ - if (!client_is_unmanaged(c)) - wlr_xwayland_surface_activate(c->surface.xwayland, 1); + /* Only "managed" windows can be activated */ + if (!client_is_unmanaged(c)) + wlr_xwayland_surface_activate(c->surface.xwayland, 1); - if (!c || !c->foreign_toplevel) - return; + if (!c || !c->foreign_toplevel) + return; - if (focus_on_activate && c != selmon->sel) { - view(&(Arg){.ui = c->tags},true); - focusclient(c,1); - } else if(c != focustop(selmon)) { - if (client_surface(c)->mapped) - client_set_border_color(c, urgentcolor); //在使用窗口剪切补丁后,这里启动gdm-settings的字体更改那里点击就会崩溃,增加过滤条件为是toplevel窗口后似乎已经解决 - c->isurgent = 1; - printstatus(); - } + if (focus_on_activate && c != selmon->sel) { + view(&(Arg){.ui = c->tags}, true); + focusclient(c, 1); + } else if (c != focustop(selmon)) { + if (client_surface(c)->mapped) + client_set_border_color( + c, + urgentcolor); // 在使用窗口剪切补丁后,这里启动gdm-settings的字体更改那里点击就会崩溃,增加过滤条件为是toplevel窗口后似乎已经解决 + c->isurgent = 1; + printstatus(); + } } -void //0.7 -configurex11(struct wl_listener *listener, void *data) -{ - Client *c = wl_container_of(listener, c, configure); - struct wlr_xwayland_surface_configure_event *event = data; - if (!client_surface(c) || !client_surface(c)->mapped) { - wlr_xwayland_surface_configure(c->surface.xwayland, - event->x, event->y, event->width, event->height); - return; - } - if (client_is_unmanaged(c)) { - wlr_scene_node_set_position(&c->scene->node, event->x, event->y); - wlr_xwayland_surface_configure(c->surface.xwayland, - event->x, event->y, event->width, event->height); - return; - } - if ((c->isfloating && c != grabc) || !c->mon->lt[c->mon->sellt]->arrange) - resize(c, (struct wlr_box){.x = event->x - c->bw, .y = event->y - c->bw, - .width = event->width + c->bw * 2, .height = event->height + c->bw * 2}, 0); - else - arrange(c->mon,false); +void // 0.7 +configurex11(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, configure); + struct wlr_xwayland_surface_configure_event *event = data; + if (!client_surface(c) || !client_surface(c)->mapped) { + wlr_xwayland_surface_configure(c->surface.xwayland, event->x, event->y, + event->width, event->height); + return; + } + if (client_is_unmanaged(c)) { + wlr_scene_node_set_position(&c->scene->node, event->x, event->y); + wlr_xwayland_surface_configure(c->surface.xwayland, event->x, event->y, + event->width, event->height); + return; + } + if ((c->isfloating && c != grabc) || !c->mon->lt[c->mon->sellt]->arrange) + resize(c, + (struct wlr_box){.x = event->x - c->bw, + .y = event->y - c->bw, + .width = event->width + c->bw * 2, + .height = event->height + c->bw * 2}, + 0); + else + arrange(c->mon, false); } /*创建窗口监测函数*/ -void -createnotifyx11(struct wl_listener *listener, void *data) -{ - struct wlr_xwayland_surface *xsurface = data; - Client *c; +void createnotifyx11(struct wl_listener *listener, void *data) { + struct wlr_xwayland_surface *xsurface = data; + Client *c; - /* Allocate a Client for this surface */ - c = xsurface->data = ecalloc(1, sizeof(*c)); - c->surface.xwayland = xsurface; - c->type = X11; - c->bw = borderpx; + /* Allocate a Client for this surface */ + c = xsurface->data = ecalloc(1, sizeof(*c)); + c->surface.xwayland = xsurface; + c->type = X11; + c->bw = borderpx; - /* Listen to the various events it can emit */ - LISTEN(&xsurface->events.associate, &c->associate, associatex11); - LISTEN(&xsurface->events.dissociate, &c->dissociate, dissociatex11); - LISTEN(&xsurface->events.request_activate, &c->activate, activatex11); - LISTEN(&xsurface->events.request_configure, &c->configure, configurex11); - LISTEN(&xsurface->events.set_hints, &c->set_hints, sethints); - LISTEN(&xsurface->events.set_title, &c->set_title, updatetitle); - LISTEN(&xsurface->events.destroy, &c->destroy, destroynotify); - LISTEN(&xsurface->events.request_fullscreen, &c->fullscreen, fullscreennotify); - LISTEN(&xsurface->events.request_maximize, &c->maximize, maximizenotify); - LISTEN(&xsurface->events.request_minimize, &c->minimize, minimizenotify); + /* Listen to the various events it can emit */ + LISTEN(&xsurface->events.associate, &c->associate, associatex11); + LISTEN(&xsurface->events.dissociate, &c->dissociate, dissociatex11); + LISTEN(&xsurface->events.request_activate, &c->activate, activatex11); + LISTEN(&xsurface->events.request_configure, &c->configure, configurex11); + LISTEN(&xsurface->events.set_hints, &c->set_hints, sethints); + LISTEN(&xsurface->events.set_title, &c->set_title, updatetitle); + LISTEN(&xsurface->events.destroy, &c->destroy, destroynotify); + LISTEN(&xsurface->events.request_fullscreen, &c->fullscreen, + fullscreennotify); + LISTEN(&xsurface->events.request_maximize, &c->maximize, maximizenotify); + LISTEN(&xsurface->events.request_minimize, &c->minimize, minimizenotify); } -Atom -getatom(xcb_connection_t *xc, const char *name) -{ - Atom atom = 0; - xcb_intern_atom_reply_t *reply; - xcb_intern_atom_cookie_t cookie = xcb_intern_atom(xc, 0, strlen(name), name); - if ((reply = xcb_intern_atom_reply(xc, cookie, NULL))) - atom = reply->atom; - free(reply); +Atom getatom(xcb_connection_t *xc, const char *name) { + Atom atom = 0; + xcb_intern_atom_reply_t *reply; + xcb_intern_atom_cookie_t cookie = xcb_intern_atom(xc, 0, strlen(name), name); + if ((reply = xcb_intern_atom_reply(xc, cookie, NULL))) + atom = reply->atom; + free(reply); - return atom; + return atom; } -void -sethints(struct wl_listener *listener, void *data) -{ - Client *c = wl_container_of(listener, c, set_hints); - if (c != focustop(selmon)) { - c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints); - printstatus(); - } +void sethints(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, set_hints); + if (c != focustop(selmon)) { + c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints); + printstatus(); + } } -void -xwaylandready(struct wl_listener *listener, void *data) -{ - struct wlr_xcursor *xcursor; - xcb_connection_t *xc = xcb_connect(xwayland->display_name, NULL); - int err = xcb_connection_has_error(xc); - if (err) { - fprintf(stderr, "xcb_connect to X server failed with code %d\n. Continuing with degraded functionality.\n", err); - return; - } +void xwaylandready(struct wl_listener *listener, void *data) { + struct wlr_xcursor *xcursor; + xcb_connection_t *xc = xcb_connect(xwayland->display_name, NULL); + int err = xcb_connection_has_error(xc); + if (err) { + fprintf(stderr, + "xcb_connect to X server failed with code %d\n. Continuing with " + "degraded functionality.\n", + err); + return; + } - /* Collect atoms we are interested in. If getatom returns 0, we will - * not detect that window type. */ - netatom[NetWMWindowTypeDialog] = getatom(xc, "_NET_WM_WINDOW_TYPE_DIALOG"); - netatom[NetWMWindowTypeSplash] = getatom(xc, "_NET_WM_WINDOW_TYPE_SPLASH"); - netatom[NetWMWindowTypeToolbar] = getatom(xc, "_NET_WM_WINDOW_TYPE_TOOLBAR"); - netatom[NetWMWindowTypeUtility] = getatom(xc, "_NET_WM_WINDOW_TYPE_UTILITY"); + /* Collect atoms we are interested in. If getatom returns 0, we will + * not detect that window type. */ + netatom[NetWMWindowTypeDialog] = getatom(xc, "_NET_WM_WINDOW_TYPE_DIALOG"); + netatom[NetWMWindowTypeSplash] = getatom(xc, "_NET_WM_WINDOW_TYPE_SPLASH"); + netatom[NetWMWindowTypeToolbar] = getatom(xc, "_NET_WM_WINDOW_TYPE_TOOLBAR"); + netatom[NetWMWindowTypeUtility] = getatom(xc, "_NET_WM_WINDOW_TYPE_UTILITY"); - /* assign the one and only seat */ - wlr_xwayland_set_seat(xwayland, seat); + /* assign the one and only seat */ + wlr_xwayland_set_seat(xwayland, seat); - /* Set the default XWayland cursor to match the rest of dwl. */ - if ((xcursor = wlr_xcursor_manager_get_xcursor(cursor_mgr, "left_ptr", 1))) - wlr_xwayland_set_cursor(xwayland, - xcursor->images[0]->buffer, xcursor->images[0]->width * 4, - xcursor->images[0]->width, xcursor->images[0]->height, - xcursor->images[0]->hotspot_x, xcursor->images[0]->hotspot_y); + /* Set the default XWayland cursor to match the rest of dwl. */ + if ((xcursor = wlr_xcursor_manager_get_xcursor(cursor_mgr, "left_ptr", 1))) + wlr_xwayland_set_cursor( + xwayland, xcursor->images[0]->buffer, xcursor->images[0]->width * 4, + xcursor->images[0]->width, xcursor->images[0]->height, + xcursor->images[0]->hotspot_x, xcursor->images[0]->hotspot_y); - xcb_disconnect(xc); + xcb_disconnect(xc); } #endif -int -main(int argc, char *argv[]) -{ - char *startup_cmd = NULL; - int c; +int main(int argc, char *argv[]) { + char *startup_cmd = NULL; + int c; - while ((c = getopt(argc, argv, "s:hdv")) != -1) { - if (c == 's') - startup_cmd = optarg; - else if (c == 'd') - log_level = WLR_DEBUG; - else if (c == 'v') - die("dwl " VERSION); - else - goto usage; - } - if (optind < argc) - goto usage; + while ((c = getopt(argc, argv, "s:hdv")) != -1) { + if (c == 's') + startup_cmd = optarg; + else if (c == 'd') + log_level = WLR_DEBUG; + else if (c == 'v') + die("dwl " VERSION); + else + goto usage; + } + if (optind < argc) + goto usage; - /* Wayland requires XDG_RUNTIME_DIR for creating its communications socket */ - if (!getenv("XDG_RUNTIME_DIR")) - die("XDG_RUNTIME_DIR must be set"); - setup(); - run(startup_cmd); - cleanup(); - return EXIT_SUCCESS; + /* Wayland requires XDG_RUNTIME_DIR for creating its communications socket */ + if (!getenv("XDG_RUNTIME_DIR")) + die("XDG_RUNTIME_DIR must be set"); + setup(); + run(startup_cmd); + cleanup(); + return EXIT_SUCCESS; usage: - die("Usage: %s [-v] [-d] [-s startup command]", argv[0]); + die("Usage: %s [-v] [-d] [-s startup command]", argv[0]); } \ No newline at end of file