Skip to content

Conversation

Blinue
Copy link
Owner

@Blinue Blinue commented Feb 11, 2025

Close #135
Close #1052
Close #959

这个 PR 用于跟踪开发进度和收集反馈。已实现的功能:

  • 全屏模式缩放时禁用了源窗口的标题栏和大小调整。
  • 切换前台窗口不会中止缩放,且缩放窗口不再总是置顶。现在源窗口是缩放窗口的所有者,这确保了缩放窗口始终在源窗口之上。技术上缩放窗口不再需要置顶,但置顶有助于在旧设备上激活 DirectFlip,因此当源窗口位于前台,缩放窗口仍会置顶。
    • 因此不再需要“记忆缩放窗口”功能。
    • 已知问题:Win10 的文件资源管理器存在兼容性问题,置顶总是失败。
  • 如果源窗口不在前台,允许鼠标进入黑边。
  • 游戏内叠加层上添加开发者选项和调试信息,打开开发者模式后可以使用。
  • 窗口化缩放时缩放窗口和源窗口保持风格一致。
  • 缩放窗口支持调整大小,存在最小和最大尺寸限制。调整大小时长宽比保持不变。
  • 鼠标在源窗口的标题栏或叠加层工具栏上可以拖动缩放窗口。
  • 不再使用 imgui.ini,叠加层位置保存在配置文件中。叠加层支持贴靠在窗口边缘。
  • 工具栏提供截图功能,开启开发者模式后还可以导出任意通道的任意输出,这对调试着色器很有帮助。效果输出导出格式为 png,中间结果导出格式为 dds。
  • TouchHelper 和 Updater 支持记录日志,保存在 %TEMP% 中。

@Blinue Blinue added the enhancement New feature or request label Feb 11, 2025
@@ -210,28 +242,142 @@ ScalingError ScalingWindow::Create(
};
RegisterClassEx(&wcex);

wcex.lpfnWndProc = DefWindowProc;
wcex.lpszClassName = CommonSharedConstants::SWAP_CHAIN_CHILD_WINDOW_CLASS_NAME;

This comment was marked as outdated.

@hooke007
Copy link
Collaborator

hooke007 commented Feb 15, 2025

窗口下使用的话,最小帧率给的太低了,强制看慢动作一样,至少要60fps
理想情况至少120fps(我的显示器是240Hz,两边并行使用不同的app,左边240fps在刷网页,右边30fps在刷程序,这个体感很微妙,特别是上下滚动内容的视觉体验特别黏腻)

@Blinue
Copy link
Owner Author

Blinue commented Feb 16, 2025

窗口下使用的话,最小帧率给的太低了,强制看慢动作一样,至少要60fps
理想情况至少120fps(我的显示器是240Hz,两边并行使用不同的app,左边240fps在刷网页,右边30fps在刷程序,这个体感很微妙,特别是上下滚动内容的视觉体验特别黏腻)

最小帧率不影响流畅度,你限制最大帧率了吗

@hooke007
Copy link
Collaborator

没有限制最大帧率

@hooke007
Copy link
Collaborator

hooke007 commented Feb 16, 2025

Magpie.2025.02.16.-.14.38.20.02.mp4

录了一个高糊的120fps视频,不知道能不能看出来,缩放前后滚动的手感有点发粘。

@Blinue
Copy link
Owner Author

Blinue commented Feb 16, 2025

滚动时帧率多少

@hooke007
Copy link
Collaborator

大部分时间30-50左右,没超过60fps

@Blinue
Copy link
Owner Author

Blinue commented Feb 16, 2025

是帧率低导致的,换个缩放模式或捕获试试

@hooke007
Copy link
Collaborator

hooke007 commented Feb 16, 2025

是帧率的问题,但是最低帧稳不住,需要提高下限。
DD能慢慢接近120fps,这时候是流畅的,需要鼠标和画面一直保持大幅变化才能维持,一旦开始回落就开始卡手了
GDI和DWM不能使用

@Blinue
Copy link
Owner Author

Blinue commented Feb 16, 2025

看起来是因为功耗不稳定,那么全屏化也有同样的问题

@hooke007
Copy link
Collaborator

hooke007 commented Feb 16, 2025

是的全屏也是一样的。窗口化的使用放大了这个差异,因为和旁边的程序不在一个流畅度上。

@Blinue
Copy link
Owner Author

Blinue commented Feb 16, 2025

引入最低帧率就是为了解决这个问题,最高可以设置成 30FPS,这也不够吗

@hooke007
Copy link
Collaborator

30FPS 实在太低了。。。我显卡够你放240我都没问题

@Blinue
Copy link
Owner Author

Blinue commented Feb 16, 2025

主流显示器还是60Hz,而且最低帧率的目的是维持显卡的能耗等级,和显示器刷新率无关。这个问题和窗口化无关就新开议题讨论吧,增加选项很容易,但需要你测试一下。

@Blinue
Copy link
Owner Author

Blinue commented Feb 19, 2025

窗口化缩放有两个大原则:

  1. 缩放窗口风格尽量贴近源窗口,比如边框和圆角风格保持一致。一个例外是阴影,阴影可以提高窗口边缘的对比度,也有助于区分前台和非前台窗口,因此缩放窗口始终有阴影。
  2. 缩放窗口支持在边框外调整尺寸,避免对操作源窗口产生干扰。Windows 窗口上边缘都是在边框内调整尺寸,因此至少需要一个辅助窗口来拦截上边框外的鼠标操作。

下面是窗口分类,我见过的窗口都可以归类到其中一种

  1. 原生
    原生

    • 典型窗口:命令提示符
    • 窗口样式:需要 WS_CAPTION
    • 特征:系统标题栏和边框,有阴影,左右下三边在窗口外调整大小,Win11 中有圆角
    • 处理:缩放窗口应保持风格一致,而且上边框应在窗口外调整大小,因此需要一个辅助窗口。如果没有裁剪且捕获标题栏,可以考虑只捕获客户区并添加原生标题栏。
  2. 无标题栏
    无标题栏

    • 典型窗口:UWP
    • 实现方式:使用 WM_NCCALCSIZE 移除系统标题栏,然后自绘上边框(极少数窗口实现了系统原生上边框,如 Windows Terminal 和 Magpie),Win11 中上边框由 OS 绘制到客户区内
    • 窗口样式:需要 WS_CAPTION
    • 特征:无标题栏,系统边框(上边框可能自绘),有阴影,左右下三边在窗口外调整大小,Win11 中有圆角
    • 处理:同 1
  3. 无边框
    无边框_Win10
    无边框_Win11

    • 典型窗口:VSCode
    • 实现方式:使用 WM_NCCALCSIZE 移除边框,然后使用 DwmExtendFrameIntoClientArea 恢复阴影
    • 窗口样式:需要 WS_CAPTION 或 WS_THICKFRAME
    • 特征:无标题栏,是否有边框取决于 OS 版本(Win10 中不存在边框,Win11 中边框被绘制到客户区内),有阴影,在窗口内调整大小,Win11 中有圆角
    • 处理:缩放窗口应保持风格一致,这意味着 Win10 和 Win11 上缩放窗口应使用不同的风格。Win10 中如果要移除边框但保留阴影,必须使用和源窗口相同的方式,另外我们需要在窗口外调整大小,因此需要 4 个辅助窗口。Win11 中这类窗口有着特殊的边框,因此和 Win10 的处理方式相同,不同的地方在于客户区内存在边框,捕获时应把边框裁剪掉,缩放窗口也应在四周为边框保留空间。
    • 备注:正常情况下位于前台时窗口阴影会变深,但某些窗口的阴影始终不变(大部分基于 electron),这可以通过WM_NCACTIVATE 实现,不清楚是 bug 还是故意为之。这种行为破坏了视觉效果的一致性,因此缩放后不会遵守这一点
  4. 无边框和阴影
    无边框和阴影

    • 典型窗口:微信
    • 实现方式:通过 WM_NCCALCSIZE 移除边框,不使用 DwmExtendFrameIntoClientArea
    • 窗口样式:任意
    • 特征:无标题栏、边框和阴影,在窗口内调整大小,Win11 中无圆角
    • 处理:同 3。原因在于无法确定窗口是否使用了 DwmExtendFrameIntoClientArea,因此没办法获知它是否有阴影。由于这个限制,我们假设所有使用 WM_NCCALCSIZE 移除边框的窗口都有阴影,一方面有阴影的情况更多,比如基于 electron 的窗口,另一方面如果假设没有阴影会使得 Win11 中不能正确裁剪边框导致黑边,而如果假设有阴影,猜错的后果相对较轻。
  5. 无边框和阴影2

    • 实现方式:特殊窗口样式
    • 窗口样式:无 WS_CAPTION、WS_BORDER 和 WS_THICKFRAME
    • 特征:无标题栏,边框和阴影,在窗口内调整大小,Win11 中无圆角
    • 处理:这类窗口外观和 4 相同,但我们可以精确判断。源窗口太朴素,甚至没办法区分是否有焦点,缩放时有必要添加阴影。Win10 中处理方式同 3,Win11 中则同 2 并禁用边框和圆角,优点是只需一个辅助窗口。

下面是不包含 WS_CAPTION 样式的窗口类型,它们很罕见,方便的话可以支持。WS_OVERLAPPED 和 WS_POPUP 唯一的区别在于前者会自动添加 WS_CAPTION 样式,如果手动移除 WS_CAPTION 样式,两者没有区别。

  1. WS_THICKFRAME
    WS_THICKFRAME

    • 窗口样式:无 WS_CAPTION(即 WS_BORDER | WS_DLGFRAME),存在 WS_THICKFRAME
    • 特征:无标题栏,系统边框但上边框较粗,有阴影,左右下三边在窗口外调整大小,Win11 中有圆角
    • 处理:技术上这类窗口和 1 唯一的区别在于标题栏很窄只能容纳调整窗口大小的区域。处理方式和 1 类似,但即使捕获标题栏也应把上边框裁剪掉。
  2. WS_BORDER
    WS_BORDER

    • 窗口样式:无 WS_THICKFRAME 和 WS_DLGFRAME,存在 WS_BORDER
    • 特征:无标题栏和阴影,深色边框(包括上边框)位于客户区外,边框宽度和窗口是否被 DPI 虚拟化有关,Win11 中无圆角
    • 处理:和其他类型差别很大,视同 5
  3. WS_DLGFRAME
    WS_DLGFRAME

    • 窗口样式:无 WS_THICKFRAME 和 WS_BORDER,存在 WS_DLGFRAME
    • 特征:无标题栏和阴影,3D 样式的边框位于客户区内,Win11 中无圆角
    • 处理:和其他类型差别很大,视同 5

@Blinue
Copy link
Owner Author

Blinue commented Jun 24, 2025

还是这个游戏,光标移动到toolbar会瞬间弹到下方

已修复

@hooke007
Copy link
Collaborator

额没有区别。还是接触的瞬间就把光标反弹了

@Blinue
Copy link
Owner Author

Blinue commented Jun 25, 2025

额没有区别。还是接触的瞬间就把光标反弹了

看来是我没遇到过的错误,要找到原因才能修复

@hooke007
Copy link
Collaborator

https://github.com/search?q=repo%3AFunkyFr3sh%2Fcnc-ddraw%20DevmodeLbl&type=code

禁用了cnc-ddraw的光标限制就不会反弹了

@Blinue
Copy link
Owner Author

Blinue commented Jun 25, 2025

禁用了cnc-ddraw的光标限制就不会反弹了

光标移到工具栏上会移出游戏窗口,然后 cnc-ddraw 又移回去。这个选项和 Magpie 冲突

@Blinue
Copy link
Owner Author

Blinue commented Jun 30, 2025

窗口化的开发现在告一段落,我没想到可以走这么远,感谢测试和反馈的你们!很快会发布测试版。

@Blinue Blinue merged commit a547630 into dev Jun 30, 2025
4 checks passed
@Blinue Blinue deleted the windowed-mode branch June 30, 2025 11:53
@HornyPrivateGamer
Copy link

HornyPrivateGamer commented Aug 14, 2025

看到上面那个issue说的,依葫芦画瓢,我增加了下快捷键隐藏光标,实现了

Hi Just wondering How did you do it.

I wanted this feature to be back so much
@bluelaze bluelaze

thansk

@bluelaze
Copy link

看到上面那个issue说的,依葫芦画瓢,我增加了下快捷键隐藏光标,实现了

Hi Just wondering How did you do it.

I wanted this feature to be back so much @bluelaze bluelaze

thansk

I clone this repo and create local branch base the delete hotkey commit from the dev branch to modify, but now the dev bransh is deleted, rebase all commit in the one commit to merge, so current not a good way to reproduce it.
But others have raised this suggestion, and the author is currently preparing to add this feature back in disguise, so you can wait for the next version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
7 participants