Xlib 和滚动

问题描述 投票:0回答:2

我不知道如何处理滚动 1000 个窗口的列表。我在一列中有 1000 个窗口。列比窗口高,因为列表中的每个窗口都是 40 像素高,所以列高 40000 像素。

我尝试了两件事。

  1. 我改变了它们中每一个的 Y 位置,并用

    XMoveWindow
    移动它们,我的速度慢于 16 毫秒,并且有一些闪烁。总而言之,这不是一个可扩展的解决方案。所以这不起作用。

  2. 我制作了一个 40000 像素高的窗口,但是如果我移动它,Xlib 会引发错误

    BadAlloc (insufficient resources for operation)

有一个 Xlib 手册,其中包含在窗口中滚动某些文本的示例。您将文本绘制到像素图中,并在滚动文本时从某个点将

Pixmap
复制到带有
Window
XCopyArea
中。再说一遍,我真的不明白如何处理一大块文本,因为你无法创建一个大的
Pixmap

如何滚动 1000 个窗口?引用 Xlib 函数甚至 C/D/Rust/Python/C++/Go/Java 中的代码片段的想法值得赞赏。

x11 xlib
2个回答
1
投票

资源总是有限的。您无法创建“巨大”像素图,但您可以做的是创建“无数”较小的像素图。

将所有数据渲染为单个像素图(每个项目一个像素图)并将它们存储在列表中。根据您的滚动位置,只有相关的像素图会被传输到窗口中。

举个例子,如果你的像素图有固定的高度(在你的例子中是 40px)并且滚动位置是

90
,那么
90/40 = 2
,这意味着你开始使用 y 位置索引
2
处的像素图进行渲染
-10
并且您只渲染适合窗口的像素图。

只需要一个窗口,不需要频繁的映射和取消映射,并且每次滚动事件都没有窗口移动请求。

唯一的缺点是,按键和指针事件必须以不同的方式处理。


如何处理按键和指针事件:

如果您在窗口上收到这些事件,只需计算(再次基于滚动位置)哪个项目受到影响(请记住,xevents 确实包含 x 和 y 坐标 - 如果发生关键事件,您必须记住选择了哪个项目,因此您必须跟踪上次活动中选择的项目)。

我不知道这种不便是否可以证明管理数百(数千)个“未使用”窗口以及相应的服务器往返行程是合理的。


0
投票

n。米。可能是人工智能在评论中回答了我的问题。映射那些可见的按钮并取消映射其余的按钮对于 1000 个按钮来说效果很好。 CPU负载接近1%,消耗的内存并没有那么高。低于 4MB。我猜测内存是为进程 Xorg 分配的。

但我发现自己画了大约 25000 个按钮。而且所有这些都是可见的。我有一排按钮。如果有帮助的话,它实际上是一个火焰图。花了几秒钟,这对我来说不起作用。对于这种情况,Erdal Küçük 的答案有效。一项澄清。在我的例子中找到光标下的按钮非常简单,因为:

  1. 每个按钮都有相同的高度(H),所以找到按钮所在的行是O(1)。我将鼠标光标的 X 坐标除以 H。它给出了带有按钮的行数。
  2. 我有一个数组,其中按钮按 X 坐标排序。因此按钮会自动按行排序。我使用二分查找,所以需要 O(log(n))。

工作速度足够快,即使对于悬停事件(当鼠标位于按钮上时)也是如此。 CPU 利用率勉强达到 1%。

© www.soinside.com 2019 - 2024. All rights reserved.