ANtlord
ANtlord

Reputation: 75

Xlib and scrolling

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.

Upvotes: 0

Views: 335

Answers (2)

ANtlord
ANtlord

Reputation: 75

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%.

Upvotes: 0

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.

Upvotes: 1

Related Questions