From 9c8c9965b652654203dded6b4fb56e167d10c6ae Mon Sep 17 00:00:00 2001 From: gsm <406643764@qq.com> Date: Sun, 12 Feb 2023 17:48:15 +0800 Subject: [PATCH] =?UTF-8?q?=20=20=20=20=20=20=20=20*=20=E7=99=BC=E5=B8=83?= =?UTF-8?q?=E7=AC=AC1.8.8=E7=89=88=EF=BC=9B=20=20=20=20=20=20=20=20=20*=20?= =?UTF-8?q?=E4=BF=AE=E5=BE=A9=E6=9F=90=E4=BA=9B=E6=83=85=E6=B3=81=E4=B8=8B?= =?UTF-8?q?=E7=AA=97=E5=8F=A3=E5=B0=BA=E5=AF=B8=E5=92=8C=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E7=95=B0=E5=B8=B8=E7=9A=84=E7=BC=BA=E9=99=B7=EF=BC=9B=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20*=20=E4=BF=AE=E5=BE=A9handle=5Fevent=E5=87=BD?= =?UTF-8?q?=E6=95=B8=E5=9C=A8=E6=9F=90=E4=BA=9B=E6=83=85=E6=B3=81=E4=B8=8B?= =?UTF-8?q?=E8=B6=8A=E7=95=8C=E8=A8=AA=E5=95=8F=E6=95=B8=E7=B5=84event=5Fh?= =?UTF-8?q?andlers=E7=9A=84=E7=BC=BA=E9=99=B7=EF=BC=9B=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20*=20=E4=BF=AE=E5=BE=A9clear=5Fwm=E5=87=BD=E6=95=B8?= =?UTF-8?q?=E6=9C=AA=E6=AA=A2=E6=9F=A5xic=E5=92=8Cxim=E6=98=AF=E5=90=A6?= =?UTF-8?q?=E7=88=B2=E7=A9=BA=E6=8C=87=E9=87=9D=E7=9A=84=E7=BC=BA=E9=99=B7?= =?UTF-8?q?=EF=BC=9B=20=20=20=20=20=20=20=20=20*=20=E4=BF=AE=E5=BE=A9?= =?UTF-8?q?=E5=AE=9A=E4=BD=8D=E5=99=A8=E7=84=A1=E6=B3=95=E6=89=93=E9=96=8B?= =?UTF-8?q?=E9=81=8B=E8=A1=8C=E8=BC=B8=E5=85=A5=E6=A1=86=E7=9A=84=E7=BC=BA?= =?UTF-8?q?=E9=99=B7=EF=BC=9B=20=20=20=20=20=20=20=20=20*=20dock=E9=A1=9E?= =?UTF-8?q?=E5=9E=8B=E7=9A=84=E7=AA=97=E5=8F=A3=E4=B8=8D=E5=86=8D=E5=8A=A0?= =?UTF-8?q?=E7=AA=97=E5=8F=A3=E8=A3=9D=E9=A3=BE=EF=BC=9B=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20*=20=E4=BF=AE=E6=94=B9=E5=B0=BA=E5=AF=B8=E8=AA=BF?= =?UTF-8?q?=E6=95=B4=E6=AD=A5=E9=80=B2=E5=80=BC=EF=BC=9B=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20*=20=E4=BF=AE=E6=94=B9=E9=BB=98=E8=AA=8D=E7=9A=84?= =?UTF-8?q?=E7=AA=97=E5=8F=A3=E9=96=93=E8=B7=9D=EF=BC=9B=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20*=20=E4=BF=AE=E6=94=B9=E6=89=80=E6=96=B0=E6=89=93?= =?UTF-8?q?=E9=96=8B=E7=9A=84=E7=B6=B2=E7=B5=A1=E7=80=8F=E8=A6=BD=E5=99=A8?= =?UTF-8?q?=E7=9A=84=E7=B6=B2=E5=9D=80=EF=BC=9B=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?*=20=E4=BB=A3=E7=A2=BC=E9=87=8D=E6=A7=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AUTHORS | 2 +- ChangeLog | 14 +++- INSTALL | 2 +- Makefile | 2 +- NEWS | 11 ++- README | 4 +- THANKS | 2 +- TODO | 7 +- man/Makefile | 2 +- man/zh_HK/Makefile | 2 +- man/zh_HK/man1/Makefile | 2 +- man/zh_HK/man1/gwm.1 | 6 +- src/Makefile | 2 +- src/client.c | 100 +++++++++++++-------------- src/client.h | 4 +- src/color.c | 2 +- src/color.h | 2 +- src/config.h | 8 +-- src/desktop.c | 2 +- src/desktop.h | 2 +- src/drawable.c | 2 +- src/drawable.h | 2 +- src/entry.c | 2 +- src/entry.h | 2 +- src/font.c | 2 +- src/font.h | 2 +- src/func.c | 146 +++++++++++++++++++++++++--------------- src/func.h | 2 +- src/grab.c | 2 +- src/grab.h | 2 +- src/gwm.c | 2 +- src/gwm.h | 9 +-- src/handler.c | 6 +- src/handler.h | 2 +- src/hint.c | 131 ++++++++++++++++++++--------------- src/hint.h | 8 +-- src/icon.c | 2 +- src/icon.h | 2 +- src/init.c | 2 +- src/init.h | 2 +- src/layout.c | 4 +- src/layout.h | 2 +- src/menu.c | 2 +- src/menu.h | 2 +- src/misc.c | 19 +++++- src/misc.h | 4 +- tools/Makefile | 2 +- tools/startgwm | 2 +- 48 files changed, 324 insertions(+), 221 deletions(-) diff --git a/AUTHORS b/AUTHORS index d7a0f44..f2f3ff1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,6 +1,6 @@ /* ************************************************************************* * AUTHORS:開發者列表。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/ChangeLog b/ChangeLog index 0aa9eb7..7b3d417 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,6 @@ /* ************************************************************************* * ChangeLog:面向開發者的變更日志。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 @@ -9,6 +9,18 @@ * 。 * ************************************************************************/ +2023年 02月 12日 星期日 17:39:55 CST gsm <406643764@qq.com> + * 發布第1.8.8版; + * 修復某些情況下窗口尺寸和位置異常的缺陷; + * 修復handle_event函數在某些情況下越界訪問數組event_handlers的缺陷; + * 修復clear_wm函數未檢查xic和xim是否爲空指針的缺陷; + * 修復定位器無法打開運行輸入框的缺陷; + * dock類型的窗口不再加窗口裝飾; + * 修改尺寸調整步進值; + * 修改默認的窗口間距; + * 修改所新打開的網絡瀏覽器的網址; + * 代碼重構。 + 2022年 12月 08日 星期四 18:03:56 CST gsm <406643764@qq.com> * 發布第1.8.7版; * 修復未初始化wm_hint的缺陷; diff --git a/INSTALL b/INSTALL index 81158db..a86c3ae 100644 --- a/INSTALL +++ b/INSTALL @@ -1,6 +1,6 @@ /* ************************************************************************* * INSTALL:安裝和卸載指南。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/Makefile b/Makefile index d32ee5b..0360f91 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # ************************************************************************* # Makefile:軟件包根目錄下的總控Makefile文件。 -# 版權 (C) 2020-2022 gsm <406643764@qq.com> +# 版權 (C) 2020-2023 gsm <406643764@qq.com> # 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 # GNU通用公共許可證重新發布、修改本程序。 # 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/NEWS b/NEWS index cb11847..d3cf210 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ /* ************************************************************************* * NEWS:面向用戶的開發新聞。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 @@ -9,6 +9,15 @@ * 。 * ************************************************************************/ +第1.8.8版: + * 修復某些情況下窗口尺寸和位置異常的缺陷; + * 修復某些情況下崩潰的缺陷; + * 修復定位器無法打開運行輸入框的缺陷; + * dock類型的窗口不再加窗口裝飾; + * 修改尺寸調整步進值; + * 修改默認的窗口間距; + * 修改所新打開的網絡瀏覽器的網址。 + 第1.8.7版: * 修復離開某些窗口時出現錯誤提示的缺陷; * 修復某些情況下光標形狀異常的缺陷; diff --git a/README b/README index fa147c1..4336ac9 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ /* ************************************************************************* * README:說明文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 @@ -12,7 +12,7 @@ 配置方法:修改config.h文件。 安裝方法:請參閱INSTALL。 使用方法:詳見gwm(1)。安裝之後,用man gwm命令來查看手冊。 -軟件首頁:https://sourceforge.net/projects/gsmwm/。 +軟件首頁:https://sourceforge.net/projects/gsmwm/ 。 漏洞報告:406643764@qq.com。 作者:詳見AUTHORS。 捐助:提交gwm的缺陷反饋、功能建議、補丁就是對gwm最大的捐助;當然,對於捐款這 diff --git a/THANKS b/THANKS index 7169534..d42f878 100644 --- a/THANKS +++ b/THANKS @@ -1,6 +1,6 @@ /* ************************************************************************* * THANKS:鳴謝。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/TODO b/TODO index a859416..eeec243 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,6 @@ /* ************************************************************************* * TODO:開發計劃。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 @@ -9,6 +9,11 @@ * 。 * ************************************************************************/ +第1.8.8版的下一步的開發計劃: + * 繼續完善臨時窗口相關功能; + * 修改響應聚焦請求的邏輯; + * 手冊頁改爲按功能分類。 + 第1.8.7版的下一步的開發計劃: * 繼續完善臨時窗口相關功能。 diff --git a/man/Makefile b/man/Makefile index 12c4c09..5893afc 100644 --- a/man/Makefile +++ b/man/Makefile @@ -1,6 +1,6 @@ # ************************************************************************* # Makefile:調用當前子目錄下的Makefile文件。 -# 版權 (C) 2020-2022 gsm <406643764@qq.com> +# 版權 (C) 2020-2023 gsm <406643764@qq.com> # 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 # GNU通用公共許可證重新發布、修改本程序。 # 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/man/zh_HK/Makefile b/man/zh_HK/Makefile index 730d858..fe01b4f 100644 --- a/man/zh_HK/Makefile +++ b/man/zh_HK/Makefile @@ -1,6 +1,6 @@ # ************************************************************************* # Makefile:調用當前子目錄下的Makefile文件。 -# 版權 (C) 2020-2022 gsm <406643764@qq.com> +# 版權 (C) 2020-2023 gsm <406643764@qq.com> # 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 # GNU通用公共許可證重新發布、修改本程序。 # 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/man/zh_HK/man1/Makefile b/man/zh_HK/man1/Makefile index 63e5ac3..417ebae 100644 --- a/man/zh_HK/man1/Makefile +++ b/man/zh_HK/man1/Makefile @@ -1,6 +1,6 @@ # ************************************************************************* # Makefile:執行當前目錄下與man1手冊頁相關的任務。 -# 版權 (C) 2020-2022 gsm <406643764@qq.com> +# 版權 (C) 2020-2023 gsm <406643764@qq.com> # 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 # GNU通用公共許可證重新發布、修改本程序。 # 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/man/zh_HK/man1/gwm.1 b/man/zh_HK/man1/gwm.1 index ba263ff..2604600 100644 --- a/man/zh_HK/man1/gwm.1 +++ b/man/zh_HK/man1/gwm.1 @@ -1,6 +1,6 @@ ./" ************************************************************************* ./" gwm.1:gwm(1)手冊頁。 -./" 版權 (C) 2020-2022 gsm <406643764@qq.com> +./" 版權 (C) 2020-2023 gsm <406643764@qq.com> ./" 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 ./" GNU通用公共許可證重新發布、修改本程序。 ./" 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 @@ -8,7 +8,7 @@ ./" 你應該已經收到一份附隨此程序的GNU通用公共許可證副本。否則,請參閱 ./" 。 ./" ************************************************************************/ -.TH gwm 1 2022年12月 "gwm 1.8.7" gwm +.TH gwm 1 2023年2月 "gwm 1.8.8" gwm . .SH 名稱 gwm \- gwm(gsm's window manager),是一個用C語言編寫的基於X11的動態窗口管理器。 @@ -508,6 +508,6 @@ gwm啓動後會立即嘗試執行~/.config/gwm/autostart.sh。 . .SH 版權 . -版權 \(co 2020-2022 gsm <406643764@qq.com>。 +版權 \(co 2020-2023 gsm <406643764@qq.com>。 .br 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的GNU通用公共許可證重新發布、修改本程序。 diff --git a/src/Makefile b/src/Makefile index b45486b..acfd811 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,6 +1,6 @@ # ************************************************************************* # Makefile:執行與源代碼相關的任務。 -# 版權 (C) 2020-2022 gsm <406643764@qq.com> +# 版權 (C) 2020-2023 gsm <406643764@qq.com> # 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 # GNU通用公共許可證重新發布、修改本程序。 # 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/client.c b/src/client.c index b1f6e72..6f6b6eb 100644 --- a/src/client.c +++ b/src/client.c @@ -1,6 +1,6 @@ /* ************************************************************************* * client.c:實現X client相關功能。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 @@ -22,9 +22,13 @@ static void apply_rules(WM *wm, Client *c); static bool have_rule(Rule *r, Client *c); -static void set_default_pos(WM *wm, Client *c, XWindowAttributes *a); -static void set_default_size(WM *wm, Client *c, XWindowAttributes *a); -static void fix_size_by_hint(Client *c); +void set_win_rect_by_attr(WM *wm, Client *c); +static void fix_win_pos(WM *wm, Client *c); +static bool fix_win_pos_by_hint(Client *c); +static void fix_win_pos_by_prop(WM *wm, Client *c); +static void fix_win_pos_by_screen(WM *wm, Client *c); +static void fix_win_size(WM *wm, Client *c); +static void fix_win_size_by_screen(WM *wm, Client *c); static void frame_client(WM *wm, Client *c); static Rect get_button_rect(Client *c, size_t index); static Rect get_frame_rect(Client *c); @@ -47,7 +51,7 @@ void add_client(WM *wm, Window win) apply_rules(wm, c); add_client_node(get_area_head(wm, c->area_type), c); fix_area_type(wm); - set_default_rect(wm, c); + set_default_win_rect(wm, c); frame_client(wm, c); if(c->area_type == ICONIFY_AREA) iconify(wm, c); @@ -69,8 +73,11 @@ static void apply_rules(WM *wm, Client *c) || type != wm->ewmh_atom[_NET_WM_WINDOW_TYPE_NORMAL] || state == wm->ewmh_atom[_NET_WM_STATE_MODAL]) c->area_type=FLOATING_AREA; - c->border_w=BORDER_WIDTH; - c->title_bar_h=TITLE_BAR_HEIGHT; + if(type != wm->ewmh_atom[_NET_WM_WINDOW_TYPE_DOCK]) + { + c->border_w=BORDER_WIDTH; + c->title_bar_h=TITLE_BAR_HEIGHT; + } c->desktop_mask=get_desktop_mask(wm->cur_desktop); c->class_hint.res_class=c->class_hint.res_name=NULL, c->class_name="?"; if(XGetClassHint(wm->display, c->win, &c->class_hint)) @@ -124,32 +131,51 @@ void fix_area_type(WM *wm) } } -void set_default_rect(WM *wm, Client *c) +void set_default_win_rect(WM *wm, Client *c) +{ + set_win_rect_by_attr(wm, c); + fix_win_size(wm, c); + fix_win_pos(wm, c); +} + +void set_win_rect_by_attr(WM *wm, Client *c) { XWindowAttributes a={0, 0, wm->screen_width/4, wm->screen_height/4}; XGetWindowAttributes(wm->display, c->win, &a); - set_default_size(wm, c, &a); - set_default_pos(wm, c, &a); + c->x=a.x, c->y=a.y, c->w=a.width, c->h=a.height; } -static void set_default_pos(WM *wm, Client *c, XWindowAttributes *a) +static void fix_win_pos(WM *wm, Client *c) +{ + if(!fix_win_pos_by_hint(c)) + fix_win_pos_by_prop(wm, c), fix_win_pos_by_screen(wm, c); +} + +static bool fix_win_pos_by_hint(Client *c) { XSizeHints *p=&c->size_hint; - c->x=p->x, c->y=p->y; if((p->flags & USPosition)) - return; + c->x=p->x, c->y=p->y; + return (p->flags & USPosition); +} +static void fix_win_pos_by_prop(WM *wm, Client *c) +{ Client *oc; // 爲了避免有符號整數與無符號整數之間的運算帶來符號問題 - long w=c->w, h=c->h, bw=c->border_w, bh=c->title_bar_h, - sw=wm->screen_width, sh=wm->screen_height, th=wm->taskbar.h; - if(!(p->flags & PPosition)) - c->x=a->x, c->y=a->y; + int w=c->w, h=c->h, bh=c->title_bar_h, sw=wm->screen_width, sh=wm->screen_height; if((oc=win_to_client(wm, get_transient_for(wm, c->win)))) c->x=oc->x+(oc->w-w)/2, c->y=oc->y+(oc->h-h)/2; if( get_atom_prop(wm, c->win, wm->ewmh_atom[_NET_WM_WINDOW_TYPE]) == wm->ewmh_atom[_NET_WM_WINDOW_TYPE_DIALOG]) c->x=(sw-w)/2, c->y=(sh-h-bh)/2+bh; +} + +static void fix_win_pos_by_screen(WM *wm, Client *c) +{ + // 爲了避免有符號整數與無符號整數之間的運算帶來符號問題 + int w=c->w, h=c->h, bw=c->border_w, bh=c->title_bar_h, + sw=wm->screen_width, sh=wm->screen_height, th=wm->taskbar.h; if(c->x >= sw-w-bw) c->x=sw-w-bw; if(c->x < bw) @@ -160,45 +186,19 @@ static void set_default_pos(WM *wm, Client *c, XWindowAttributes *a) c->y=bw+bh; } -static void set_default_size(WM *wm, Client *c, XWindowAttributes *a) +static void fix_win_size(WM *wm, Client *c) +{ + fix_win_size_by_hint(c); + fix_win_size_by_screen(wm, c); +} + +static void fix_win_size_by_screen(WM *wm, Client *c) { unsigned int sw=wm->screen_width, sh=wm->screen_height, th=wm->taskbar.h; - XSizeHints *p=&c->size_hint; - - if(p->width && p->height) - c->w=p->width, c->h=p->height; - else - c->w=a->width, c->h=a->height; - if(c->w+2*c->border_w > sw) c->w=sw-2*c->border_w; if(c->h+c->title_bar_h+2*c->border_w > sh-th) c->h=sh-th-c->title_bar_h-2*c->border_w; - c->w=p->base_width+get_client_col(wm, c)*p->width_inc; - c->h=p->base_height+get_client_row(wm, c)*p->height_inc; - fix_size_by_hint(c); -} - -static void fix_size_by_hint(Client *c) -{ - XSizeHints *p=&c->size_hint; - if(p->min_width && c->wmin_width) - c->w=p->min_width; - if(p->min_height && c->hmin_height) - c->h=p->min_height; - if(p->max_width && c->w>p->max_width) - c->w=p->max_width; - if(p->max_height && c->h>p->max_height) - c->h=p->max_height; - if(p->min_aspect.x && p->min_aspect.y) - { - float mina=(float)p->min_aspect.x/p->min_aspect.y, - maxa=(float)p->max_aspect.x/p->max_aspect.y; - if((float)c->w/c->h < mina) - c->h=c->w*mina+0.5; - else if((float)c->w/c->h > maxa) - c->w=c->h*maxa+0.5; - } } static void frame_client(WM *wm, Client *c) diff --git a/src/client.h b/src/client.h index da40ee9..a3e1a8d 100644 --- a/src/client.h +++ b/src/client.h @@ -1,6 +1,6 @@ /* ************************************************************************* * client.h:與client.c相應的頭文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 @@ -15,7 +15,7 @@ void add_client(WM *wm, Window win); void add_client_node(Client *head, Client *c); void fix_area_type(WM *wm); -void set_default_rect(WM *wm, Client *c); +void set_default_win_rect(WM *wm, Client *c); void create_title_bar(WM *wm, Client *c); Rect get_title_area_rect(WM *wm, Client *c); unsigned int get_typed_clients_n(WM *wm, Area_type type); diff --git a/src/color.c b/src/color.c index 0c473b4..bac54ce 100644 --- a/src/color.c +++ b/src/color.c @@ -1,6 +1,6 @@ /* ************************************************************************* * color.c:實現分配顏色的功能。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/color.h b/src/color.h index a2b5606..a315c95 100644 --- a/src/color.h +++ b/src/color.h @@ -1,6 +1,6 @@ /* ************************************************************************* * color.h:與color.c相應的頭文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/config.h b/src/config.h index 1c9f2e9..4250ad7 100644 --- a/src/config.h +++ b/src/config.h @@ -1,6 +1,6 @@ /* ************************************************************************* * config.h:gwm的配置文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 @@ -45,7 +45,6 @@ #define DEFAULT_N_MAIN_MAX 1 // 默認的主區域最大窗口數量 #define AUTOSTART "~/.config/gwm/autostart.sh" // 在gwm剛啓動時執行的腳本 #define CMD_CENTER_COL 4 // 操作中心按鈕列數 -#define MOVE_RESIZE_INC 8 // 移動窗口、調整窗口尺寸的步進值,單位爲像素。僅當窗口未有效設置尺寸特性時才使用它。 #define DEFAULT_FONT_PIXEL_SIZE 24 // 默認字體大小,單位爲像素 #define TITLE_FONT_PIXEL_SIZE DEFAULT_FONT_PIXEL_SIZE // 標題欄的字體大小,單位爲像素 @@ -59,7 +58,7 @@ #define TITLE_BAR_HEIGHT ROUND(TITLE_FONT_PIXEL_SIZE*4/3.0) // 窗口標題欄的高度,單位爲像素 #define TITLE_BUTTON_WIDTH TITLE_BAR_HEIGHT // 窗口按鈕的寬度,單位爲像素 #define TITLE_BUTTON_HEIGHT TITLE_BUTTON_WIDTH // 窗口按鈕的高度,單位爲像素 -#define WIN_GAP BORDER_WIDTH // 窗口間隔,單位爲像素 +#define WIN_GAP (BORDER_WIDTH*2) // 窗口間隔,單位爲像素 #define STATUS_AREA_WIDTH_MAX TASKBAR_FONT_PIXEL_SIZE*30 // 任務欄狀態區域的最大寬度 #define TASKBAR_HEIGHT ROUND(TASKBAR_FONT_PIXEL_SIZE*4/3.0) // 狀態欄的高度,單位爲像素 #define TASKBAR_BUTTON_WIDTH TASKBAR_FONT_PIXEL_SIZE*2 // 任務欄按鈕的寬度,單位爲像素 @@ -74,6 +73,7 @@ #define RUN_CMD_ENTRY_WIDTH (ENTRY_FONT_PIXEL_SIZE*15+ENTRY_TEXT_INDENT*2) // 運行命令的輸入構件的寬度,單位爲像素 #define RUN_CMD_ENTRY_HEIGHT ROUND(ENTRY_FONT_PIXEL_SIZE*4/3.0) // 運行命令的輸入構件的寬度,單位爲像素 #define HINT_WIN_LINE_HEIGHT ROUND(HINT_FONT_PIXEL_SIZE*4/3.0) // 提示窗口的行高度,單位爲像素 +#define RESIZE_INC DEFAULT_FONT_PIXEL_SIZE // 調整尺寸的步進值,單位爲像素。當應用於窗口時,僅當窗口未有效設置尺寸特性時才使用它。 #define RUN_CMD_ENTRY_HINT L"請輸入命令,然後按回車執行" #define DEFAULT_FONT_NAME "monospace:pixelsize="TO_STR(DEFAULT_FONT_PIXEL_SIZE) // 默認字體名 @@ -178,7 +178,7 @@ #define HELP "lxterminal -e 'man gwm' || xfce4-terminal -e 'man gwm' || xterm -e 'man gwm'" #define FILE_MANAGER "xdg-open ~" -#define BROWSER "xdg-open http:" +#define BROWSER "xdg-open http://bing.com" #define TERMINAL "lxterminal || xfce4-terminal || gnome-terminal || konsole5 || xterm" #define VOLUME_DOWN "amixer -q sset Master 10%-" #define VOLUME_UP "amixer -q sset Master 10%+" diff --git a/src/desktop.c b/src/desktop.c index a54ec57..7392667 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -1,6 +1,6 @@ /* ************************************************************************* * desktop.c:實現虛擬桌面功能。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/desktop.h b/src/desktop.h index dbfe515..d25da16 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -1,6 +1,6 @@ /* ************************************************************************* * desktop.h:與desktop.c相應的頭文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/drawable.c b/src/drawable.c index 8918021..d17f2d7 100644 --- a/src/drawable.c +++ b/src/drawable.c @@ -1,6 +1,6 @@ /* ************************************************************************* * drawable.c:實現與X可畫物相關功能。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/drawable.h b/src/drawable.h index 5720fd1..5abdf97 100644 --- a/src/drawable.h +++ b/src/drawable.h @@ -1,6 +1,6 @@ /* ************************************************************************* * drawable.h:與drawable.c相應的頭文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/entry.c b/src/entry.c index 67a7994..5953f2d 100644 --- a/src/entry.c +++ b/src/entry.c @@ -1,6 +1,6 @@ /* ************************************************************************* * entry.c:實現單行文本輸入框功能。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/entry.h b/src/entry.h index a220e72..3e8b899 100644 --- a/src/entry.h +++ b/src/entry.h @@ -1,6 +1,6 @@ /* ************************************************************************* * entry.h:與entry.c相應的頭文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/font.c b/src/font.c index b2bc453..9826715 100644 --- a/src/font.c +++ b/src/font.c @@ -1,6 +1,6 @@ /* ************************************************************************* * font.c:實現字體相關功能。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/font.h b/src/font.h index 883cee9..c153ee3 100644 --- a/src/font.h +++ b/src/font.h @@ -1,6 +1,6 @@ /* ************************************************************************* * font.h:與font.c相應的頭文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/func.c b/src/func.c index f4f3a31..ae09ba4 100644 --- a/src/func.c +++ b/src/func.c @@ -1,6 +1,6 @@ /* ************************************************************************* * func.c:實現按鍵和按鍵所要綁定的功能。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 @@ -29,9 +29,13 @@ static bool is_match_button_release(WM *wm, XEvent *oe, XEvent *ne); static bool is_valid_click(WM *wm, XEvent *oe, XEvent *ne); static Delta_rect get_key_delta_rect(Client *c, Direction dir); -static bool is_prefer_move_resize(WM *wm, Client *c, Delta_rect *d); -static bool fix_move_resize(WM *wm, Client *c, Delta_rect *d); -static void do_valid_pointer_move_resize(WM *wm, Client *c, Move_info *m, Pointer_act act, bool is_resize); +static void do_valid_pointer_move_resize(WM *wm, Client *c, Move_info *m, Pointer_act act); +static bool fix_move_resize_delta_rect(WM *wm, Client *c, Delta_rect *d, bool is_move); +static bool is_prefer_move(WM *wm, Client *c, Delta_rect *d, bool is_move); +static bool fix_delta_rect_for_nonprefer_size(Client *c, XSizeHints *hint, Delta_rect *d); +static void fix_dw_by_width_hint(int w, XSizeHints *hint, int *dw); +static void fix_dh_by_height_hint(int h, XSizeHints *hint, int *dh); +static bool fix_delta_rect_for_prefer_size(Client *c, XSizeHints *hint, int dw, int dh, Delta_rect *d); static void update_hint_win_for_resize(WM *wm, Client *c); static Delta_rect get_pointer_delta_rect(const Move_info *m, Pointer_act act); @@ -101,11 +105,13 @@ void key_move_resize_client(WM *wm, XEvent *e, Func_arg arg) { if(DESKTOP(wm).cur_layout==TILE || DESKTOP(wm).cur_layout==STACK) { + Direction dir=arg.direction; + bool is_move = (dir==UP || dir==DOWN || dir==LEFT || dir==RIGHT); Client *c=DESKTOP(wm).cur_focus_client; - Delta_rect d=get_key_delta_rect(c, arg.direction); + Delta_rect d=get_key_delta_rect(c, dir); if(c->area_type!=FLOATING_AREA && DESKTOP(wm).cur_layout==TILE) move_client(wm, c, get_area_head(wm, FLOATING_AREA), FLOATING_AREA); - if(is_prefer_move_resize(wm, c, &d) || fix_move_resize(wm, c, &d)) + if(fix_move_resize_delta_rect(wm, c, &d, is_move)) { move_resize_client(wm, c, &d); update_hint_win_for_resize(wm, c); @@ -147,43 +153,6 @@ static Delta_rect get_key_delta_rect(Client *c, Direction dir) return dr[dir]; } -static bool is_prefer_move_resize(WM *wm, Client *c, Delta_rect *d) -{ - return ( ((!d->dw && !d->dh) - && is_on_screen(wm, c->x+d->dx, c->y+d->dy, c->w+d->dw, c->h+d->dh)) - || is_prefer_resize(wm, c, d)); -} - -static bool fix_move_resize(WM *wm, Client *c, Delta_rect *d) -{ - XSizeHints *p=&c->size_hint; - long w=c->w, h=c->h, cw=w, ch=h, dw=d->dw, dh=d->dh; - if((dw || dh) && (!is_prefer_size(w, h, p) || !is_prefer_aspect(w, h, p))) - { - if(p->min_width) - w=cw=MAX(cw, p->min_width); - if(p->min_height) - h=ch=MAX(ch, p->min_height); - if(p->max_width) - w=cw=MIN(cw, p->max_width); - if(p->max_height) - h=ch=MIN(ch, p->max_height); - if(dw) - for(w=p->base_width; ;w+=p->width_inc) - if(is_prefer_size(w, ch, p) && is_prefer_aspect(w, ch, p)) - break; - if(dh) - for(h=p->base_height; ;h+=p->height_inc) - if(is_prefer_size(w, h, p) && is_prefer_aspect(w, h, p)) - break; - d->dw=w-cw, d->dh=h-ch; - // 修正尺寸時,應確保尺寸變化方向上鄰近光標的邊與光標的間距基本不變 - d->dx = d->dx ? d->dx : -d->dw, d->dy = d->dy ? d->dy : -d->dh; - return true; - } - return false; -} - void quit_wm(WM *wm, XEvent *e, Func_arg arg) { clear_wm(wm); @@ -238,7 +207,7 @@ void adjust_main_area_ratio(WM *wm, XEvent *e, Func_arg arg) Desktop *d=&DESKTOP(wm); double mr=d->main_area_ratio+arg.change_ratio, fr=d->fixed_area_ratio; int mw=mr*wm->screen_width, sw=wm->screen_width*(1-fr)-mw; - if(sw>=MOVE_RESIZE_INC && mw>=MOVE_RESIZE_INC) + if(sw>=RESIZE_INC && mw>=RESIZE_INC) { d->main_area_ratio=mr; update_layout(wm); @@ -254,7 +223,7 @@ void adjust_fixed_area_ratio(WM *wm, XEvent *e, Func_arg arg) Desktop *d=&DESKTOP(wm); double fr=d->fixed_area_ratio+arg.change_ratio, mr=d->main_area_ratio; int mw=wm->screen_width*(mr-arg.change_ratio), fw=wm->screen_width*fr; - if(mw>=MOVE_RESIZE_INC && fw>=MOVE_RESIZE_INC) + if(mw>=RESIZE_INC && fw>=RESIZE_INC) { d->main_area_ratio-=arg.change_ratio, d->fixed_area_ratio=fr; update_layout(wm); @@ -326,7 +295,7 @@ void pointer_move_resize_client(WM *wm, XEvent *e, Func_arg arg) move_client(wm, c, get_area_head(wm, FLOATING_AREA), FLOATING_AREA); /* 因X事件是異步的,故xmotion.x和ev.xmotion.y可能不是連續變化 */ m.nx=ev.xmotion.x, m.ny=ev.xmotion.y; - do_valid_pointer_move_resize(wm, c, &m, act, arg.resize); + do_valid_pointer_move_resize(wm, c, &m, act); } else handle_event(wm, &ev); @@ -335,19 +304,18 @@ void pointer_move_resize_client(WM *wm, XEvent *e, Func_arg arg) XUnmapWindow(wm->display, wm->hint_win); } -static void do_valid_pointer_move_resize(WM *wm, Client *c, Move_info *m, Pointer_act act, bool is_resize) +static void do_valid_pointer_move_resize(WM *wm, Client *c, Move_info *m, Pointer_act act) { - bool fix; Delta_rect d=get_pointer_delta_rect(m, act); - if(is_prefer_move_resize(wm, c, &d) || (fix=fix_move_resize(wm, c, &d))) + if(fix_move_resize_delta_rect(wm, c, &d, act==MOVE)) { move_resize_client(wm, c, &d); update_hint_win_for_resize(wm, c); - if(is_resize) + if(act != MOVE) { - if(!fix && d.dw) // dx爲0表示定位器從窗口右邊調整尺寸,非0則表示左邊調整 + if(d.dw) // dx爲0表示定位器從窗口右邊調整尺寸,非0則表示左邊調整 m->ox = d.dx ? m->ox-d.dw : m->ox+d.dw; - if(!fix && d.dh) // dy爲0表示定位器從窗口下邊調整尺寸,非0則表示上邊調整 + if(d.dh) // dy爲0表示定位器從窗口下邊調整尺寸,非0則表示上邊調整 m->oy = d.dy ? m->oy-d.dh : m->oy+d.dh; } else @@ -355,10 +323,80 @@ static void do_valid_pointer_move_resize(WM *wm, Client *c, Move_info *m, Pointe } } +static bool fix_move_resize_delta_rect(WM *wm, Client *c, Delta_rect *d, bool is_move) +{ + if( is_prefer_move(wm, c, d, is_move) + || fix_delta_rect_for_nonprefer_size(c, &c->size_hint, d)) + return true; + + int dw=d->dw, dh=d->dh; + fix_dw_by_width_hint(c->w, &c->size_hint, &dw); + fix_dh_by_height_hint(c->w, &c->size_hint, &dh); + return fix_delta_rect_for_prefer_size(c, &c->size_hint, dw, dh, d); +} + +static bool is_prefer_move(WM *wm, Client *c, Delta_rect *d, bool is_move) +{ + return (is_move && is_on_screen(wm, c->x+d->dx, c->y+d->dy, c->w, c->h)); +} + +static bool fix_delta_rect_for_nonprefer_size(Client *c, XSizeHints *hint, Delta_rect *d) +{ + if((d->dw || d->dh) && !is_prefer_size(c->w, c->h, hint)) // 首次調整尺寸時才要考慮爲偏好而修正尺寸 + { + int ox=c->x, oy=c->y, ow=c->w, oh=c->h; + fix_win_size_by_hint(c); + d->dx=c->x-ox, d->dy=c->y-oy, d->dw=(int)c->w-ow, d->dh=(int)c->h-oh; + c->x=ox, c->y=oy, c->w=ow, c->h=oh; + return true; + } + return false; +} + +static void fix_dw_by_width_hint(int w, XSizeHints *hint, int *dw) +{ + if(*dw/hint->width_inc) + { + int max=MAX(hint->width_inc, hint->min_width); + *dw=base_n_floor(*dw, hint->width_inc); + if(w+*dw < max) + *dw=max-w; + } + else + *dw=0; +} + +static void fix_dh_by_height_hint(int h, XSizeHints *hint, int *dh) +{ + if(*dh/hint->height_inc) + { + int max=MAX(hint->height_inc, hint->min_height); + *dh=base_n_floor(*dh, hint->height_inc); + if(h+*dh < max) + *dh=max-h; + } + else + *dh=0; +} + +static bool fix_delta_rect_for_prefer_size(Client *c, XSizeHints *hint, int dw, int dh, Delta_rect *d) +{ + if((dw || dh) && is_prefer_size(c->w+dw, c->h+dh, hint)) + { + d->dw=dw, d->dh=dh; + if(d->dx) + d->dx=-dw; + if(d->dy) + d->dy=-dh; + return true; + } + return false; +} + static void update_hint_win_for_resize(WM *wm, Client *c) { char str[BUFSIZ]; - unsigned int w=get_client_col(wm, c), h=get_client_row(wm, c); + unsigned int w=get_client_col(c), h=get_client_row(c); sprintf(str, "(%d, %d) %ux%u", c->x, c->y, w, h); get_string_size(wm, wm->font[HINT_FONT], str, &w, NULL); int x=(wm->screen_width-w)/2, y=(wm->screen_height-HINT_WIN_LINE_HEIGHT)/2; @@ -430,7 +468,7 @@ void adjust_layout_ratio(WM *wm, XEvent *e, Func_arg arg) if(ev.type == MotionNotify) { nx=ev.xmotion.x, dx=nx-ox; - if(abs(dx)>=MOVE_RESIZE_INC && change_layout_ratio(wm, ox, nx)) + if(abs(dx)>=RESIZE_INC && change_layout_ratio(wm, ox, nx)) update_layout(wm), ox=nx; } else diff --git a/src/func.h b/src/func.h index 9474ec5..8ffd41f 100644 --- a/src/func.h +++ b/src/func.h @@ -1,6 +1,6 @@ /* ************************************************************************* * func.h:與func.c相應的頭文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/grab.c b/src/grab.c index c711210..b634779 100644 --- a/src/grab.c +++ b/src/grab.c @@ -1,6 +1,6 @@ /* ************************************************************************* * grab.c:實現獨享按鍵、按鈕功能。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/grab.h b/src/grab.h index 8b20bdc..de68118 100644 --- a/src/grab.h +++ b/src/grab.h @@ -1,6 +1,6 @@ /* ************************************************************************* * grab.h:與grab.c相應的頭文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/gwm.c b/src/gwm.c index 2978148..9600197 100644 --- a/src/gwm.c +++ b/src/gwm.c @@ -1,6 +1,6 @@ /* ************************************************************************* * gwm.c:實現窗口管理器的主要部分。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/gwm.h b/src/gwm.h index 46866ca..16e6140 100644 --- a/src/gwm.h +++ b/src/gwm.h @@ -1,6 +1,6 @@ /* ************************************************************************* * gwm.h:與gwm.c相應的頭文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 @@ -23,7 +23,7 @@ #include "config.h" #define ICCCM_NAMES (const char *[]) {"WM_PROTOCOLS", "WM_DELETE_WINDOW", "WM_TAKE_FOCUS"} -#define EWMH_NAME (const char *[]) {"_NET_WM_WINDOW_TYPE", "_NET_WM_WINDOW_TYPE_NORMAL", "_NET_WM_WINDOW_TYPE_DIALOG", "_NET_WM_STATE", "_NET_WM_STATE_MODAL", "_NET_WM_ICON"} +#define EWMH_NAME (const char *[]) {"_NET_WM_WINDOW_TYPE", "_NET_WM_WINDOW_TYPE_NORMAL", "_NET_WM_WINDOW_TYPE_DIALOG", "_NET_WM_WINDOW_TYPE_DOCK", "_NET_WM_STATE", "_NET_WM_STATE_MODAL", "_NET_WM_ICON"} #define MIN(a, b) ((a)<(b) ? (a) : (b)) #define MAX(a, b) ((a)>(b) ? (a) : (b)) @@ -195,6 +195,7 @@ typedef enum icccm_atom_tag Icccm_atom; enum ewmh_atom_tag // EWMH規範的標識符 { _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_NORMAL, _NET_WM_WINDOW_TYPE_DIALOG, + _NET_WM_WINDOW_TYPE_DOCK, _NET_WM_STATE, _NET_WM_STATE_MODAL, _NET_WM_ICON, EWMH_ATOM_N }; typedef enum ewmh_atom_tag Ewmh_atom; @@ -341,9 +342,9 @@ struct rule_tag // 窗口管理器的規則 }; typedef struct rule_tag Rule; -struct move_info_tag /* 定位器舊、新坐標信息 */ +struct move_info_tag /* 定位器所點擊的窗口位置每次合理移動或調整尺寸所對應的舊、新坐標信息 */ { - int ox, oy, nx, ny; /* 分別爲定位器舊、新坐標 */ + int ox, oy, nx, ny; /* 分別爲舊、新坐標 */ }; typedef struct move_info_tag Move_info; diff --git a/src/handler.c b/src/handler.c index 72385ea..364f721 100644 --- a/src/handler.c +++ b/src/handler.c @@ -1,6 +1,6 @@ /* ************************************************************************* * handler.c:實現X事件處理功能。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 @@ -80,7 +80,7 @@ void handle_event(WM *wm, XEvent *e) [PropertyNotify] = handle_property_notify, [SelectionNotify] = handle_selection_notify, }; - if(event_handlers[e->type]) + if(e->typetype]) event_handlers[e->type](wm, e); } @@ -102,7 +102,7 @@ static void handle_button_press(WM *wm, XEvent *e) } if(type != CMD_CENTER_ITEM) XUnmapWindow(wm->display, wm->cmd_center.win); - if(type != RUN_CMD_ENTRY) + if(type!=RUN_CMD_ENTRY && type!=RUN_BUTTON) XUnmapWindow(wm->display, wm->run_cmd.win); } diff --git a/src/handler.h b/src/handler.h index ac2acfc..3cd3b7a 100644 --- a/src/handler.h +++ b/src/handler.h @@ -1,6 +1,6 @@ /* ************************************************************************* * handler.h:與handler.c相應的頭文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/hint.c b/src/hint.c index 8ca3bbc..7ada881 100644 --- a/src/hint.c +++ b/src/hint.c @@ -1,6 +1,6 @@ /* ************************************************************************* * hint.c:實現窗口尺寸條件特性的相關功能。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 @@ -12,19 +12,20 @@ #include "gwm.h" #include "client.h" #include "drawable.h" +#include "misc.h" #include "hint.h" -static bool is_prefer_width_inc(unsigned int w, int dw, XSizeHints *hint); -static bool is_prefer_height_inc(unsigned int h, int dh, XSizeHints *hint); -static int get_fixed_width_inc(unsigned int w, XSizeHints *hint); -static int get_fixed_height_inc(unsigned int h, XSizeHints *hint); +static void fix_limit_size_hint(XSizeHints *h); +static bool is_prefer_width(unsigned int w, XSizeHints *hint); +static bool is_prefer_height(unsigned int h, XSizeHints *hint); +static bool is_prefer_aspect(unsigned int w, unsigned int h, XSizeHints *hint); -unsigned int get_client_col(WM *wm, Client *c) +unsigned int get_client_col(Client *c) { return (c->w-c->size_hint.base_width)/c->size_hint.width_inc; } -unsigned int get_client_row(WM *wm, Client *c) +unsigned int get_client_row(Client *c) { return (c->h-c->size_hint.base_height)/c->size_hint.height_inc; } @@ -55,68 +56,90 @@ void update_size_hint(WM *wm, Client *c) if(!minh && baseh) hint.min_height=baseh; if(!hint.width_inc) - hint.width_inc=MOVE_RESIZE_INC; + hint.width_inc=RESIZE_INC; if(!hint.height_inc) - hint.height_inc=MOVE_RESIZE_INC; + hint.height_inc=RESIZE_INC; + fix_limit_size_hint(&hint); c->size_hint=hint; } - SET_DEF_VAL(c->size_hint.width_inc, MOVE_RESIZE_INC); - SET_DEF_VAL(c->size_hint.height_inc, MOVE_RESIZE_INC); + SET_DEF_VAL(c->size_hint.width_inc, RESIZE_INC); + SET_DEF_VAL(c->size_hint.height_inc, RESIZE_INC); } -bool is_prefer_resize(WM *wm, Client *c, Delta_rect *d) +// 有的窗口最大、最小尺寸設置不正確,需要修正,如:lxterminal +static void fix_limit_size_hint(XSizeHints *h) +{ + int minw_incs=base_n_ceil(h->min_width-h->base_width, h->width_inc), + minh_incs=base_n_ceil(h->min_height-h->base_height, h->height_inc), + maxw_incs=base_n_floor(h->max_width-h->base_width, h->width_inc), + maxh_incs=base_n_floor(h->max_height-h->base_height, h->height_inc); + h->min_width=h->base_width+minw_incs; + h->min_height=h->base_height+minh_incs; + h->max_width=h->base_width+maxw_incs; + h->max_height=h->base_height+maxh_incs; +} + +void fix_win_size_by_hint(Client *c) { XSizeHints *p=&c->size_hint; - long cw=c->w, ch=c->h, dw=d->dw, dh=d->dh, w=cw+dw, h=ch+dh; - return (w>=MOVE_RESIZE_INC && h>=MOVE_RESIZE_INC - && (is_prefer_width_inc(cw, dw, p) || is_prefer_height_inc(ch, dh, p)) - && is_prefer_size(w, h, p) && is_prefer_aspect(w, h, p)); -} - -static bool is_prefer_width_inc(unsigned int w, int dw, XSizeHints *hint) -{ - return !hint->width_inc || abs(dw)>=abs(get_fixed_width_inc(w, hint)); -} - -static bool is_prefer_height_inc(unsigned int h, int dh, XSizeHints *hint) -{ - return !hint->height_inc || abs(dh)>=abs(get_fixed_height_inc(h, hint)); -} - -static int get_fixed_width_inc(unsigned int w, XSizeHints *hint) -{ - int inc=MOVE_RESIZE_INC; - if(hint->base_width) - inc=(w-hint->base_width)%hint->width_inc; - else if(hint->min_width) - inc=(w-hint->min_width)%hint->width_inc; - return inc ? inc : hint->width_inc; -} - -static int get_fixed_height_inc(unsigned int h, XSizeHints *hint) -{ - int inc=MOVE_RESIZE_INC; - if(hint->base_height) - inc=(h-hint->base_height)%hint->height_inc; - else if(hint->min_height) - inc=(h-hint->min_height)%hint->height_inc; - return inc ? inc : hint->height_inc; + c->w = (p->flags & USSize) && p->width ? + p->width : p->base_width+get_client_col(c)*p->width_inc; + c->h = (p->flags & USSize) && p->height ? + p->height : p->base_height+get_client_row(c)*p->height_inc; + if((p->flags & PMinSize) && p->min_width) + c->w=MAX(c->w, p->min_width); + if((p->flags & PMinSize) && p->min_height) + c->h=MAX(c->h, p->min_height); + if((p->flags & PMaxSize) && p->max_width) + c->w=MIN(c->w, p->max_width); + if((p->flags & PMaxSize) && p->max_height) + c->h=MIN(c->h, p->max_height); + if( (p->flags & PAspect) && p->min_aspect.x && p->min_aspect.y + && p->max_aspect.x && p->max_aspect.y) + { + float mina=(float)p->min_aspect.x/p->min_aspect.y, + maxa=(float)p->max_aspect.x/p->max_aspect.y; + if((float)c->w/c->h < mina) + c->h=c->w*mina+0.5; + else if((float)c->w/c->h > maxa) + c->w=c->h*maxa+0.5; + } } bool is_prefer_size(unsigned int w, unsigned int h, XSizeHints *hint) { - return (!hint->min_width || w>=hint->min_width) - && (!hint->min_height || h>=hint->min_height) - && (!hint->max_width || w<=hint->max_width) - && (!hint->max_height || h<=hint->max_height); + return is_prefer_width(w, hint) + && is_prefer_height(h, hint) + && is_prefer_aspect(w, h, hint); } -bool is_prefer_aspect(unsigned int w, unsigned int h, XSizeHints *hint) +static bool is_prefer_width(unsigned int w, XSizeHints *hint) { - return (!hint->min_aspect.x || !hint->min_aspect.y + long f=0; + return !hint || !(f=hint->flags) || + ( (!(f & PMinSize) || w>=hint->min_width) + && (!(f & PMaxSize) || w<=hint->max_width) + && (!(f & PBaseSize) || !(f & PResizeInc) || !hint->width_inc + || (w-hint->base_width)%hint->width_inc == 0)); +} + +static bool is_prefer_height(unsigned int h, XSizeHints *hint) +{ + long f=0; + return !hint || !(f=hint->flags) || + ( (!(f & PMinSize) || h>=hint->min_height) + && (!(f & PMaxSize) || h<=hint->max_height) + && (!(f & PBaseSize) || !(f & PResizeInc) || !hint->height_inc + || (h-hint->base_height)%hint->height_inc == 0)); +} + +static bool is_prefer_aspect(unsigned int w, unsigned int h, XSizeHints *hint) +{ + return !hint || !(hint->flags & PAspect) || !w || !h + || !hint->min_aspect.x || !hint->min_aspect.y || !hint->max_aspect.x || !hint->max_aspect.y - || ( (float)w/h >= (float)hint->min_aspect.x/hint->min_aspect.y - && (float)w/h <= (float)hint->max_aspect.x/hint->max_aspect.y)); + || ( (float)w/h >= (float)hint->min_aspect.x/hint->min_aspect.y + && (float)w/h <= (float)hint->max_aspect.x/hint->max_aspect.y); } void set_input_focus(WM *wm, XWMHints *hint, Window win) diff --git a/src/hint.h b/src/hint.h index 8902fd6..5940e61 100644 --- a/src/hint.h +++ b/src/hint.h @@ -1,6 +1,6 @@ /* ************************************************************************* * hint.h:與hint.c相應的頭文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 @@ -12,12 +12,12 @@ #ifndef HINT_H #define HINT_H -unsigned int get_client_col(WM *wm, Client *c); -unsigned int get_client_row(WM *wm, Client *c); +unsigned int get_client_col(Client *c); +unsigned int get_client_row(Client *c); void update_size_hint(WM *wm, Client *c); +void fix_win_size_by_hint(Client *c); bool is_prefer_resize(WM *wm, Client *c, Delta_rect *d); bool is_prefer_size(unsigned int w, unsigned int h, XSizeHints *hint); -bool is_prefer_aspect(unsigned int w, unsigned int h, XSizeHints *hint); void set_input_focus(WM *wm, XWMHints *hint, Window win); #endif diff --git a/src/icon.c b/src/icon.c index 6da18f8..24cc0b4 100644 --- a/src/icon.c +++ b/src/icon.c @@ -1,6 +1,6 @@ /* ************************************************************************* * icon.c:實現圖符化的相關功能。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/icon.h b/src/icon.h index 8b62747..dfd12dc 100644 --- a/src/icon.h +++ b/src/icon.h @@ -1,6 +1,6 @@ /* ************************************************************************* * icon.h:與icon.c相應的頭文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/init.c b/src/init.c index 063776d..3ee6614 100644 --- a/src/init.c +++ b/src/init.c @@ -1,6 +1,6 @@ /* ************************************************************************* * init.c:實現初始化gwm的功能。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/init.h b/src/init.h index 643596a..11c3140 100644 --- a/src/init.h +++ b/src/init.h @@ -1,6 +1,6 @@ /* ************************************************************************* * init.h:與init.c相應的頭文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/layout.c b/src/layout.c index 799a927..fe70614 100644 --- a/src/layout.c +++ b/src/layout.c @@ -1,6 +1,6 @@ /* ************************************************************************* * layout.c:實現與窗口布局相關的功能。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 @@ -176,7 +176,7 @@ static void fix_cur_focus_client_rect(WM *wm) Client *c=DESKTOP(wm).cur_focus_client; if( DESKTOP(wm).prev_layout==FULL && c->area_type==FLOATING_AREA && (DESKTOP(wm).cur_layout==TILE || DESKTOP(wm).cur_layout==STACK)) - set_default_rect(wm, c); + set_default_win_rect(wm, c); } diff --git a/src/layout.h b/src/layout.h index 6f95790..bedf66d 100644 --- a/src/layout.h +++ b/src/layout.h @@ -1,6 +1,6 @@ /* ************************************************************************* * layout.h:與layout.c相應的頭文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/menu.c b/src/menu.c index 47b04ee..41e07f7 100644 --- a/src/menu.c +++ b/src/menu.c @@ -1,6 +1,6 @@ /* ************************************************************************* * menu.c:實現菜單功能。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/menu.h b/src/menu.h index c5f77e7..1a96bab 100644 --- a/src/menu.h +++ b/src/menu.h @@ -1,6 +1,6 @@ /* ************************************************************************* * menu.h:與menu.c相應的頭文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/src/misc.c b/src/misc.c index 434eb32..c6b43d9 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1,6 +1,6 @@ /* ************************************************************************* * misc.c:雜項。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 @@ -173,8 +173,11 @@ void clear_wm(WM *wm) for(size_t i=0; idisplay, wm->cursors[i]); XSetInputFocus(wm->display, wm->root_win, RevertToPointerRoot, CurrentTime); - XDestroyIC(wm->run_cmd.xic); - XCloseIM(wm->xim); + if(!wm->run_cmd.xic)puts("wtf xic"); + if(wm->run_cmd.xic) + XDestroyIC(wm->run_cmd.xic); + if(wm->xim) + XCloseIM(wm->xim); close_fonts(wm); free_files(wm->wallpapers); XClearWindow(wm->display, wm->root_win); @@ -279,3 +282,13 @@ static void create_file_node(File *head, const char *path, char *filename, bool file->next=head->next; head->next=file; } + +int base_n_floor(int x, int n) +{ + return x/n*n; +} + +int base_n_ceil(int x, int n) +{ + return base_n_floor(x, n)+(x%n ? n : 0); +} diff --git a/src/misc.h b/src/misc.h index a74e9a1..58fc11b 100644 --- a/src/misc.h +++ b/src/misc.h @@ -1,6 +1,6 @@ /* ************************************************************************* * misc.h:與misc.c相應的頭文件。 - * 版權 (C) 2020-2022 gsm <406643764@qq.com> + * 版權 (C) 2020-2023 gsm <406643764@qq.com> * 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 * GNU通用公共許可證重新發布、修改本程序。 * 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 @@ -28,5 +28,7 @@ char *copy_strings(const char *s, ...); File *get_files_in_paths(const char *paths, const char *regex, Order order, bool is_fullname, size_t *n); void free_files(File *head); bool regcmp(const char *s, const char *regex); +int base_n_floor(int x, int n); +int base_n_ceil(int x, int n); #endif diff --git a/tools/Makefile b/tools/Makefile index 718ad5d..e11c053 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,6 +1,6 @@ # ************************************************************************* # Makefile:執行與輔助工具相關的任務。 -# 版權 (C) 2020-2022 gsm <406643764@qq.com> +# 版權 (C) 2020-2023 gsm <406643764@qq.com> # 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 # GNU通用公共許可證重新發布、修改本程序。 # 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特 diff --git a/tools/startgwm b/tools/startgwm index e1b530b..fdbc7f9 100755 --- a/tools/startgwm +++ b/tools/startgwm @@ -2,7 +2,7 @@ # ************************************************************************* # startgwm:gwm會話。 -# 版權 (C) 2020-2022 gsm <406643764@qq.com> +# 版權 (C) 2020-2023 gsm <406643764@qq.com> # 本程序為自由軟件:你可以依據自由軟件基金會所發布的第三版或更高版本的 # GNU通用公共許可證重新發布、修改本程序。 # 雖然基于使用目的而發布本程序,但不負任何擔保責任,亦不包含適銷性或特