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

How are global effects disabled? #23

Closed
joaotavora opened this issue Nov 10, 2015 · 7 comments
Closed

How are global effects disabled? #23

joaotavora opened this issue Nov 10, 2015 · 7 comments

Comments

@joaotavora
Copy link

This is coming from rnkn/olivetti#6 and joaotavora/darkroom#2, and is just a question.

You say that affecting global frame settings in a minor mode isn't exactly "up and up" but you say that these effects are justified because of distraction free writing. Fair enough, but how and when are these effects undone in your implementation? If/when you undo them, how to you restore them to their previous values?

I'd gladly abandon darkroom-mode in favor of writeroom-mode (you seems to be much more actively maintaining it) if you can answer this and also provide some writeroom-tentative-mode like darkroom-tentative-mode.

@joostkremers
Copy link
Owner

You say that affecting global frame settings in a minor mode isn't exactly "up and up" but you say that these effects are justified because of distraction free writing. Fair enough, but how and when are these effects undone in your implementation? If/when you undo them, how to you restore them to their previous values?

They're undone in the function writeroom--disable, but only if you disable writeroom-mode in the last buffer in which it was active. The effects are also undone in the function writeroom--kill-buffer-function in case the last writeroom-mode buffer is killed without deactivating writeroom-mode first.

I keep a list of writeroom-mode buffers in the variable writeroom--buffers. The state of the relevant frame parameters before writeroom-mode is activated is saved in frame parameters under the same name with the prefix writeroom-. (So the state of the frame parameter fullscreen is saved under the frame parameter writeroom-fullscreen.)

Note that there are also buffer-local variables whose values are changed. These are saved in the buffer-local value writeroom--saved-data. The variables whose values must be saved are listed in writeroom--local-variables. (Perhaps I should turn that into a customisable option.)

I'd gladly abandon darkroom-mode in favor of writeroom-mode (you seems to be much more actively maintaining it) if you can answer this and also provide some writeroom-tentative-mode like darkroom-tentative-mode.

Adding something like darkroom-tentative-mode shouldn't be too difficult to do, but such a mode would only make sense if you don't use any of the global effects. Otherwise, you'll have the window decorations, scroll and menu bars etc. reappear and the frame size change every time you split a window. Alternatively, of course, writeroom-tentatively-mode would only disable the local effects temporarily.

Note that writeroom-mode readjusts the window margins every time the window size changes, and it does the right thing when the window width goes below writeroom-width, so in practice I don't think there's any need to deactivate writeroom-mode when the window is split.

But if you're willing to try out writeroom-mode and still feel it would benefit from a writeroom-tentatively-mode, let me know and I'll see what I can do.

@joostkremers
Copy link
Owner

To provide a bit more detail:

There is a macro define-writeroom-global-effect that is used to define global effects. It takes the name of a frame parameter and a value, and creates a function that sets the frame parameter to that value, and that also stores the frame parameter's original value in a new frame parameter called writeroom-<fp>, where <fp> is the original frame parameter.

These functions used to be called writeroom-toggle-<fp>, but they aren't toggles, because they explicitly set or unset a parameter, depending on the argument passed to them. So I've just renamed them to writeroom-set-<fp>.

I do see your point that the global effects (which are really frame-specific effects) go beyond what a minor mode should do, which is why they can be disabled (I do that myself, actually). I try to make sure they don't wreak havoc by not using them as toggles, by keeping a list of writeroom-mode buffers to make sure they're only activated and deactivated once, and by storing their original values in frame parameters as well, so there's no risk of interference with other frames.

Actually, I just realised that there is still a bug in the code... If you activate writeroom-mode in frame A, then switch to frame B, display the writeroom-mode buffer in it and deactivate writeroom-mode, the wrong frame will be targeted when undoing the global effects.

I should fix that.

@joaotavora
Copy link
Author

I keep a list of writeroom-mode buffers in the variable writeroom--buffers. The state of the relevant frame parameters before writeroom-mode is activated is saved in frame parameters under the same name with the prefix writeroom-. (So the state of the frame parameter fullscreen is saved under the frame parameter writeroom-fullscreen.)

But if a user changes a parameter to a different value during the usage of writeroom, for whatever reason, will the restore code catch that and not restore that parameter? If so, how do you do this?

Other than that, I see you go to great lengths to make it behave correctly. Or I should say predictably: another predictable way is to enable/disable frame effects in the presence of a writeroom-enabled buffer if there is a window showing it in the current frame. But that's perhaps more confusing.

I've skimmed the code and it looks well written and clear enough. I'll either import your global-effect managing code into darkroom.el or write up a writeroom-tentative-mode and make a pull request.

Thanks for the great writeup!

@joostkremers
Copy link
Owner

But if a user changes a parameter to a different value during the usage of writeroom, for whatever reason, will the restore code catch that and not restore that parameter? If so, how do you do this?

No, such changes aren't detected. The parameters are always restored to the value they had before writeroom-mode was first activated.

another predictable way is to enable/disable frame effects in the presence of a writeroom-enabled buffer if there is a window showing it in the current frame.

Yes, that would be an option, but I'm not sure it would be a good idea. Changing frame parameters requires redrawing the GUI window, which is not always instant (the window manager may even employ some fancy graphical effects) and it may change the location of the GUI window and/or the Emacs window you're looking at, so you'd need to reorient your eyes every time a writeroom-enabled buffer goes in or out of view.

Also, I've had bug reports that toggling fullscreen off does not always restore the frame properly. Those are probably WM bugs, but I don't want to trigger them more often than necessary.

I've skimmed the code and it looks well written and clear enough. I'll either import your global-effect managing code into darkroom.el or write up a writeroom-tentative-mode and make a pull request.

A pull request would be great!

@joostkremers
Copy link
Owner

I should fix that.

Should be fixed now in 48b1798.

@joaotavora
Copy link
Author

Apropos saving/restoring global/local effects, have a look at my proposal in the emacs devel mailing list:

https://lists.gnu.org/archive/html/emacs-devel/2015-11/msg01296.html

@joostkremers
Copy link
Owner

Apropos saving/restoring global/local effects, have a look at my proposal in the emacs devel mailing list:

https://lists.gnu.org/archive/html/emacs-devel/2015-11/msg01296.html

Yes, I saw it, but I haven't had the time yet to look at it in detail. Will hopefully do so in the next few days.

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

No branches or pull requests

2 participants