Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom button refresh time #70

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

boppy
Copy link
Contributor

@boppy boppy commented Dec 23, 2018

As supposed in #18

Mainloop.source_remove(this._cycleTimeout);
if (this._cycleTimeouts.length > 0){
this._cycleTimeouts.forEach(cycle => Mainloop.source_remove(cycle));
this._cycleTimeouts = [];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both this line, and the if check, appear to be unnecessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. I just tried to keep as close to your implementation as possible - and you've been using this source_remove there, so I just adopted it ;-)
Will remove this...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reread your comment and fixed something. Is that what you meant?

if (this._cycleTimeout !== null) {
Mainloop.source_remove(this._cycleTimeout);
this._cycleTimeout = null;
if (this._cycleTimeouts.length > 0) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here also the if check is unnecessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally. Same as :62 to :64. Will remove this...

for (let j = 0; j < buttonLines.length; j++) {
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, fullsec, Lang.bind(this, function() {
this._cycleTimeouts.push(Mainloop.timeout_add_seconds(fullsec, Lang.bind(this, function() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are there two nested timeouts here? I don't understand this part at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's the tricky part... But after some tries, it is the easiest way I found.

The first wrapping GLib.timeout_add_seconds is just to emulate a "window.setTimeout" event. It only runs once (returning false at line 154) setting the "current" line once. It takes the (current) sum of seconds as a Timeout, so next strings appear after the correct timeout.

Then the second timeout always has a fixed fullsec since the initial iteration over the lines is done and the full sum of seconds is known. This "full sum of seconds" is the timeout for EACH of the lines. Image:

  • Line A, 1 Sec.
  • Line B, 3 Sec.
  • Line C, 2 Sec.

Line A is shown directly (because fullsec is 0 on first run), Line B is shown 0+1 seconds later, Line C is shown 0+1+3 seconds later. After this first launch of the lines, the timeout does not change anymore for any of the lines, because we used the different timeouts in the first loop, so every message is displayed every 0+1+3+2 seconds from now on.

As a native German speaker I hope that I was able to describe the idea good enough to make it understandable. If not so, just keep asking... ;)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So to summarize, each line has its own independent periodic timeout with interval equal to the total timeout of all lines, and each of those timeouts is offset by another timeout equal to the sum of timeouts of all lines before it.

That's a nice idea, but it doesn't quite work. The problem is that Desktop Linux is not a realtime operating system, and functions like timeout_add_seconds don't guarantee anything with respect to wall clock time (this is actually mentioned in the GLib documentation). So in the long run, the individual _cycleTimeouts can get out of sync, to the point where the order in which the lines are displayed is changed. This can't be allowed to happen.

See the _update function in the same file for an approach that solves this problem. At the end of each cycle, a timeout is set that recursively invokes the function. The length of the timeout can depend on the cycle, and thus on the line. This also means that only one timeout is active at any given time, which saves resources.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So to summarize, each line has its own independent periodic timeout with interval equal to the total timeout of all lines, and each of those timeouts is offset by another timeout equal to the sum of timeouts of all lines before it.

check!

[...] this is actually mentioned in the GLib documentation.

check! I got the "recalculation" thing from the docs wrong... 😞

(So the) order in which the lines are displayed is changed. This can't be allowed to happen.

check!

I'll continue optimizing. Thanks for taking the time to respond.

README.md Outdated
@@ -232,6 +232,7 @@ Control how the line is rendered.
| `ansi` | `true` or `false` | If `false`, disable interpretation of ANSI escape sequences in the line text. |
| `useMarkup` | `true` or `false` | If `false`, disable interpretation of Pango markup in the line text. **Argos only.** |
| `unescape` | `true` or `false` | If `false`, disable interpretation of backslash escapes such as `\n` in the line text. **Argos only.** |
| `timeout` | Timeout in seconds | If the line is a button line, it sets how long an entry is visible (defaults to 3) **Argos only.** |
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I very much appreciate that you thought of adding documentation. However, I must ask you to remove it again, because I don't plan to push another release to the GNOME Shell extensions website anytime soon, and if what is documented here doesn't match what the version available there can do, I will be spammed with repeated questions asking why feature X doesn't work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally okay with that... Would it be an option to set the MASTER branch to the currently deployed version and set a dev branch for not-published versions? If anybody gets to the issue page and finds it closed, the same problem arises.

Since I have a head like a sieve, I would forget about adding this section again before updating the ext next time. But that might be special to my sieved coffee-input-unit... ;-P

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Having a DEV branch and MASTER being the version published is a good idea. PRs could got there we could already test new features more easily.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants