我需要模拟 Fluxbox 窗口管理器的窗口布局策略。
作为一个大致的指南,想象随机大小的窗口逐个填满屏幕,每个窗口的粗略大小平均为80个窗口,而没有任何窗口重叠。
如果您的系统上安装了Fluxbox和Xterm,您可以尝试使用xwinmidiarptoy BASH脚本来查看我想要发生的大致原型。请参阅我编写的xwinmidiarptoy.txt说明它的功能以及如何使用它。
重要的是要注意,窗口将关闭,先前关闭的窗口占用的空间再次变得可用,以便放置新的窗口。
该算法需要成为一个在线算法,以串行方式“逐个处理数据片段,即按照输入提供给算法的顺序进行处理,而不是一开始就有整个输入”。
Fluxbox窗口布局策略有三个二进制选项,我想要模拟:
Windows可以横向排列或纵向排列(可能)
窗口从左到右放置或从右到左放置
窗口从上到下放置或从下到上放置
目标算法与窗口放置算法之间的差异
坐标单位不是像素。将放置块的网格大小为128 x 128个单位。此外,放置区域可能会进一步缩小,因为在网格内还会放置边界区域。
为什么算法是个问题?
它需要在音频应用程序的实时线程截止期限内操作。
此时我只关心获得快速算法,不要担心实时线程的影响以及在编程中带来的所有障碍。
虽然该算法永远不会放置重叠的窗口,但用户将能够放置和移动某些类型的块,重叠的窗口将存在。用于存储窗口和/或空闲空间的数据结构需要能够处理此重叠。
到目前为止,我有两个选择,我已经为它们构建了松散的原型:
1)将Fluxbox放置算法移植到我的代码中。
这样做的问题是,当我尝试使用算法放置256个块的最坏情况时,客户端(我的程序)会被音频服务器(JACK)踢出。在放置第256个窗口时,该算法执行超过14000次完整(线性)扫描已放置的块列表。为了演示这一点,我创建了一个名为text_boxer-0.0.2.tar.bz2的程序,它以文本文件作为输入,并在ASCII框中排列它。运行
make
来构建它。有点不友好,使用--help
(或任何其他无效选项)获取命令行选项列表。必须使用该选项指定文本文件。
2) 我的替代方法。
这种方法只部分实现了,它为每个矩形未使用的自由空间区域使用数据结构(窗口列表可以完全分开,不需要测试此算法)。数据结构充当双向链表中的节点(具有排序插入功能),并包含左上角的坐标、宽度和高度。此外,每个块数据结构还包含四个链接,分别连接到其四个边缘上的每个立即相邻的(接触)块。
重要规则:每个块只能与每边接触一个块。这是算法存储未使用空间的特定规则,不影响任意窗口之间的实际接触。
这种方法的问题在于它非常复杂。我已经实现了直接的情况,其中1)从块的一个角落移除空间,2)分割相邻的块,以遵守重要规则。
不太直接的情况是,所要删除的空间只能在一列或一行的方框中找到,这只有部分实现——如果要删除的块恰好适合宽度(即列)或高度(即行),则会出现问题。更不用说这只检查宽度为一个盒子和高度为一个盒子的列。
我用C语言实现了这个算法——这是我用于此项目的语言(我已经几年没有使用C++了,在专注于C开发后,使用它感到不舒服,这是我的爱好)。该实现包括700多行代码(包括大量的空行、括号行、注释等)。该实现仅适用于水平行+左右+上下放置策略。
因此,我必须添加一些方法,使这+700行代码适用于其他7个放置策略选项,或者我必须将这些+700行代码复制到其他七个选项中。两者都不太理想,第一个原因是现有代码已经足够复杂,第二个原因是膨胀。
这个算法甚至还没有达到我可以在实时最坏情况下使用它的阶段,因为缺少功能,所以我仍然不知道它是否比第一种方法表现更好或更差。
当前C语言实现该算法的状态为freespace.c。我使用gcc -O0 -ggdb freespace.c
进行构建,并在至少124 x 60字符大小的xterm中运行它。
还有什么其他的吗?
我已经浏览并排除了以下内容:
装箱算法:它们强调最佳适配,与该算法的要求不符。
递归二分放置算法:听起来很有前途,但这些是用于电路设计的。它们强调最佳线长。
这两种算法,特别是后者,在算法开始之前就已知所有要放置/打包的元素。
你对此有何想法?你会如何处理?我应该看哪些其他算法?或者我应该研究哪些概念,因为我没有学习过计算机科学/软件工程?
如果需要进一步的信息,请在评论中提出问题。
自提问以来进一步发展的想法
- 我的“替代算法”与空间哈希图的某些组合,用于识别一个要放置的大窗口是否会覆盖多个自由空间块。