Xlib 和滚动

huangapple go评论56阅读模式
英文:

Xlib and scrolling

问题

我不知道如何处理滚动一个包含1000个窗口的列表。我有1000个窗口排成一列。这一列比窗口高,因为列表中的每个窗口高度为40像素,所以列的高度为40000像素。

我尝试了两种方法。

  1. 我更改了它们每一个的Y位置,并使用XMoveWindow移动它们,但我比16毫秒慢,会有闪烁。总的来说,这不是一个可扩展的解决方案。所以它不起作用。

  2. 我创建了一个高度为40000像素的窗口,但如果我移动它,Xlib会引发错误BadAlloc(操作的资源不足)

有一个Xlib手册,里面有一个示例,可以滚动窗口中的一些文本。你将文本绘制到像素图中,然后使用XCopyArea从某个点将Pixmap复制到Window中,以实现文本滚动。再次说明,我真的不明白如何处理大段文本,因为你不能创建一个大的Pixmap

我该如何滚动这1000个窗口?欢迎提供与Xlib函数相关的思路或甚至在C/D/Rust/Python/C++/Go/Java中的代码片段。

英文:

I don't how to deal with scrolling a list of 1000 windows. I have 1000 windows in a column. The column is higher than the window, because every window in the list is 40 pixels high, so the column is 40000 pixels high.

I tried 2 things.

  1. I changed the Y position of each one of them and move them with XMoveWindow, I do it slower than 16ms and get some blinking. All in all it's not a scalable solution. So it doesn't work.

  2. I made a window which is 40000 pixels high, but if I move it Xlib raises and error BadAlloc (insufficient resources for operation).

There is an Xlib manual with an example of scrolling some text in a window. You draw text into the pixmap and copy the Pixmap to the Window with XCopyArea from a certain point when you scroll the text. Again I don't really understand how to handle a big chunk of text, because you can't create a big Pixmap.

How can I scroll 1000 windows? An idea with references to Xlib functions or even a code snippet in C/D/Rust/Python/C++/Go/Java are appreciated.

答案1

得分: 1

资源始终有限。您无法创建一个'巨大'的位图,但您可以创建许多较小的位图。

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

例如,如果您的位图具有固定的高度(在您的情况下为40像素),滚动位置为90,那么90/40 = 2,这意味着您从索引2的位图开始以y位置-10渲染,并且只渲染适合窗口的位图数量。

只需要一个窗口,不需要频繁的映射和取消映射,也不需要在每次滚动事件上进行窗口移动请求。

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


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

如果在您的窗口上接收到这些事件,只需根据滚动位置再次计算受影响的项目(请记住,xevents包含x和y坐标 - 在键盘事件的情况下,您必须记住选择的项目,因此必须跟踪上次事件中选择的项目)。

我不知道这种不便是否值得管理成百上千个'未使用'窗口以及与服务器的相应往返。

英文:

The resources are always limited. You cannot create a 'gigantic' pixmap, but what you can do is to create a 'myriad' of smaller pixmaps.

Render all your data into single pixmaps (one pixmap for every item) and store them in a list. Based on your scroll position, only the relevant pixmaps are blit into the window.

As an example, if your pixmaps have a fixed height (in your case 40px) and the scroll position is 90, then 90/40 = 2, that means you start rendering with the pixmap at index 2 at the y-position -10 and you render only that many pixmaps, that would fit into the window.

Only one window required, no frequent mapping and unmapping and no window move requests on each and every scroll event.

The only downside is, that key and pointer events have to be handled in a different way.


How to handle key and pointer events:

If you receive those events on your window, simply calculate (again based on the scroll position) which item is affected (remember, the xevents do contain the x and y coordinates - in case of an key event, you'll have to remember which item is selected, so you have to keep track of the item, that was picked at the last event).

I don't know if this inconvenience justifies the management of hundreds (thousands) of 'unused' windows and the respective round trips to the server.

答案2

得分: 0

n. m. could be an AI在评论中回答了我的问题。将可见的按钮映射并取消映射其余按钮对于1000个按钮效果很好。CPU负载接近1%,内存消耗不高,低于4MB。我猜这些内存是为Xorg进程分配的。

但我发现自己要绘制大约25000个按钮,而且它们都是可见的。我有一排排的按钮。如果有帮助的话,这实际上是一个Flame图。这需要几秒钟的时间,这对我来说不合适。对于这种情况,Erdal Küçük的回答适用。一个澄清:在我的情况下,查找光标下的按钮非常简单,因为:

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

足够快,即使是悬停事件(鼠标悬停在按钮上)也可以。CPU利用率几乎不会超过1%。

英文:

n. m. could be an AI answered my question in comments. Mapping those buttons which are visible and unmapping the rest of them works just fine for 1000 buttons. The CPU load was close to 1%, the consumed memory wasn't that high. Below 4MB. I guess that the memory was allocated for the process Xorg.

But I found myself drawing about 25000 buttons. And all of them are visible. I have rows of buttons. It's actually a Flame Graph if it helps. It took a couple of seconds, which doesn't work for me. For this case the answer from Erdal Küçük worked. One clarification. Finding a button under the cursor in my case was pretty simple because:

  1. Every button has the same height (H), so to find the row of the buttons was O(1). I divided the X coordinate of the mouse cursor by H. It gives the number of row with the button.
  2. I had an array where the buttons are placed sorted by X coordinate. So the buttons were sorted in rows automatically. I use the Binary Search so it takes O(log(n)).

Works fast enough, even for hover events (when the mouse is over a button). The CPU utilization barely gets to 1%.

huangapple
  • 本文由 发表于 2023年5月24日 20:59:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76323820.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定