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

enable & handle terminal focus events #861

Closed
wants to merge 2 commits into from

Conversation

laktak
Copy link
Contributor

@laktak laktak commented Jun 29, 2022

When using lf instances in multiple panes in the same window in tmux it is hard to tell which instance has the focus. The same is true when you have multiple terminal panes side by side.

This PR allows lf to receive focus events and turns the highlight for the current selection off when lf loses focus. This means only the active lf instance will show the highlight.

Tested with tmux and kitty on Linux/macos.

@laktak
Copy link
Contributor Author

laktak commented Jun 30, 2022

Also tested on Windows, of course it does not work there but just to make sure it has no side effects.

@laktak laktak mentioned this pull request Jul 4, 2022
Comment on lines +404 to 406
if i == dir.pos && gOpts.hasfocus {
st = st.Reverse(true)
}
Copy link
Collaborator

@ilyagr ilyagr Aug 29, 2022

Choose a reason for hiding this comment

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

Thank you for making this! I'm using it, and it's nice.

However, I would personally prefer something like the following here:

		if i == dir.pos {
			st = st.Reverse(true)
			if !gOpts.hasfocus {
				st = st.Foreground(tcell.ColorDarkGray)
			}
		}

I think the grey color looks nicer than a complete absence of a selection. Of course, in the ideal world the color would be configurable; I'm not sure if this can be done through the LS_COLORS variable or somehow else.

Copy link
Collaborator

Choose a reason for hiding this comment

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

(To be clear, I have no official review powers here).

Copy link
Collaborator

Choose a reason for hiding this comment

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

I switched to tcell.ColorGray. It should support more terminal and light themes better.

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 implemented it this way to behave like a cursor in tmux - there is only one active cursor, no dimming.

So if you prefer dimming I'd like your PR to have options ;-)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I see. Here I was thinking dimming was strictly superior. Do you think dim cursors in unfocused windows are distracting? Do you not like them in general?

I was hoping to avoid an explosion of options, not sure what the best way is. One possibility is to have an on/off focusevents option and a dimcursor option with possible values gray, hide, and same that would govern what the "dimmed" cursor looks like both when focus is lost and for the directory preview (#924.).

Copy link
Contributor Author

@laktak laktak Sep 1, 2022

Choose a reason for hiding this comment

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

Do you think dim cursors in unfocused windows are distracting?

Yes, too much noise IMO.

Comment on lines +455 to 457
if i == dir.pos && gOpts.hasfocus {
win.print(screen, lnwidth+1, i, st.Reverse(true), tag)
} else {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this can be simpler. st is already the style we want, it already has Revese(true) set.

			if i == dir.pos {
				win.print(screen, lnwidth+1, i, st, tag)
			} else {

That makes it work with my suggestion above. (I may or may not get around to making these suggestions into a pull request on top of your pull request.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Here's a diff with these changes + a related feature: ilyagr/lf@13ff430...2673fc7

Copy link
Collaborator

@ilyagr ilyagr Aug 30, 2022

Choose a reason for hiding this comment

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

I now made the "related feature" into a proper pull request: #924. To make it work with focus events, the only thing that needs to change to merge with your PR is that dim_cursor: false in line 882 of ui.go (link below) has to change to dim_cursor: !gOpts.hasfocus.

https://github.com/gokcehan/lf/pull/924/files#diff-bcaef4efbe83b371a9c05e40ca6d2d0d27b63e0c9fc169993c9959397f9890ceR882

ilyagr added a commit to ilyagr/lf that referenced this pull request Aug 30, 2022
When preview is on and consists of a directory listing, make the
cursor in there dimmer to emphasize it's not active. This makes it
visually obvious which cursor is active at all times, without
having to read the path. The active cursor is now always  the
rightmost bright one, regardless of whether the `preview` option
is on or off.

See screenshots in the pull request.

Before this, I noticed that I often open a file by accident because
I got confused which of the three cursors on the screen is the active
one.

In the future, I also hope this dimming could be used to show when an lf
window loses focus, based on @laktak's implementation of focus tracking
in gokcehan#861.
ilyagr added a commit to ilyagr/lf that referenced this pull request Aug 30, 2022
When preview is on and consists of a directory listing, make the
cursor in there dimmer to emphasize it's not active. This makes it
visually obvious which cursor is active at all times, without
having to read the path. The active cursor is now always  the
rightmost bright one, regardless of whether the `preview` option
is on or off.

See screenshots in the pull request at
gokcehan#924.

Before this, I noticed that I often open a file by accident because
I got confused which of the three cursors on the screen is the active
one.

In the future, I also hope this dimming could be used to show when an lf
window loses focus, based on @laktak's implementation of focus tracking
in gokcehan#861.
client.go Outdated
app.loop()

// disable focus reporting
fmt.Print("\x1b[?1004l")
Copy link
Collaborator

@ilyagr ilyagr Aug 30, 2022

Choose a reason for hiding this comment

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

This is actually a little buggy. Let's say you run lf inside another lf. After you exit the inner lf, the outer lf no longer receives focus events.

Also, if you use lf to launch a program that gets confused by focus events, that program will get focus events and be confused.

To solve this, every time lf launches a program that might have access to the terminal (for instance $ and ! but not %), it should first disable focus reporting. After that program finishes, lf should again enable focus reporting.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, that's a good input. focus events should be disabled in that case. I'll take a look when I find the time.

Copy link
Collaborator

@ilyagr ilyagr Aug 31, 2022

Choose a reason for hiding this comment

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

You should also consider using Go's defer feature to attempt to disable focus events in cases when lf is interrupted or something panics. I'm 80% sure it's the right thing to do, would need to do a bit more research to be sure.

ilyagr added a commit to ilyagr/lf that referenced this pull request Sep 3, 2022
When preview is on and consists of a directory listing, make the
cursor in there dimmer to emphasize it's not active. This makes it
visually obvious which cursor is active at all times, without
having to read the path. The active cursor is now always  the
rightmost bright one, regardless of whether the `preview` option
is on or off.

See screenshots in the pull request at
gokcehan#924.

Before this, I noticed that I often open a file by accident because
I got confused which of the three cursors on the screen is the active
one.

In the future, I also hope this dimming could be used to show when an lf
window loses focus, based on @laktak's implementation of focus tracking
in gokcehan#861.
@ilyagr
Copy link
Collaborator

ilyagr commented Sep 10, 2022

I discovered another minor bug with this functionality. It doesn't properly handle focus events when in prompt mode.

To reproduce, open lf, press :, and make lf lose focus and gain it back again. When lf loses focus, the letter O gets added to the command prompt. When lf gains focus, I gets added to the prompt.

UPDATE: This is actually more difficult to fix than it appears. It looks like cmap doesn't currently support multi-key bindings.

@laktak
Copy link
Contributor Author

laktak commented Sep 13, 2022

@ilyagr

I discovered another minor bug with this functionality. It doesn't properly handle focus events when in prompt mode.

I've fixed this. cmap now handles multi-key bindings but only for <ESC>[ (didn't have more time and I am also not sure if there is a use case).

Also the focus events are disabled when shelling out.

Thanks and let me know if you find anything else.

@ilyagr
Copy link
Collaborator

ilyagr commented Sep 14, 2022

Thanks, this looks nice! When I get a moment, I'll switch my personal lf to use this version of this PR and perhaps look at your code more carefully. At a glance, it looks great.

cmap now handles multi-key bindings but only for [ (didn't have more time and I am also not sure if there is a use case).

I think that's fine.

BTW, I made a feature request for tcell in gdamore/tcell#558. It looks like they want to implement it. If that happens, we'll be able to make this functionality less hacky. Until then, I see no problem with using this version.

ilyagr added a commit to ilyagr/lf that referenced this pull request Sep 20, 2022
This mainly merges gokcehan#924 with @laktak's
gokcehan#861. This also merges in the `:keys`
command (gokcehan#918) as well as 
and some unrelated minor corrections (currently
dd5dc59).
ilyagr added a commit to ilyagr/lf that referenced this pull request Oct 9, 2022
This mainly merges gokcehan#924 with @laktak's
gokcehan#861. This also merges in the `:keys`
command (gokcehan#918) as well as 
and some unrelated minor corrections (currently
dd5dc59).
@gokcehan
Copy link
Owner

@laktak @ilyagr I don't think it is a good idea to hard code terminal escape codes on lf side. Feel free to submit another patch again if this is supported on tcell.

@gokcehan gokcehan closed this Oct 15, 2022
@laktak
Copy link
Contributor Author

laktak commented Oct 15, 2022

@gokcehan You are right. I'll take a look at a better solution.

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