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

rename CompostionEvent to IMEPreeditEvent #1622

Conversation

garasubo
Copy link
Contributor

@garasubo garasubo commented Jul 10, 2020

Ref: #1497 (comment)

To avoid confusion from users, rename CompositionEvent to IMEPreeditEvent to make it clear that those events are related to IME.
Also, added documents

  • Tested on all platforms changed
  • Compilation warnings were addressed
  • cargo fmt has been run on this branch
  • cargo doc builds successfully
  • Added an entry to CHANGELOG.md if knowledge of this change could be valuable to users
  • Updated documentation to reflect any user-facing changes, including notes of platform-specific behavior
  • Created or updated an example program if it would help users understand this functionality
  • Updated feature matrix, if new features were added or implemented

Copy link
Contributor

@Osspial Osspial left a comment

Choose a reason for hiding this comment

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

I’m in favor of renaming these events from CompositionEvent, but I don’t like the name IMEPreeditEvent. Is there anything wrong with just IMEEvent or ImeEvent?

@garasubo
Copy link
Contributor Author

@Osspial it makes sense for me. Will rename them.

@garasubo
Copy link
Contributor Author

@Osspial Could you check my change? I renamed them. One CI check was failed, but I think this is not related to this change.

Copy link
Member

@kchibisov kchibisov left a comment

Choose a reason for hiding this comment

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

I've rebased composition-event branch.

I also think that we can apply the proposed changes(about event restructure) from the issue I've mentioned in that PR, right now we only have X11 backend, so that's why I think it should be done here.

If you have any questions or concerns let me know.

src/event.rs Outdated
CompositionStart(String),
CompositionUpdate(String, usize),
CompositionEnd(String),
pub enum PreeditState {
Copy link
Member

Choose a reason for hiding this comment

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

I think we can name it a bit differently, since it's not only about preedit state, since you have commit, etc. I'd also like to see adoption of

pub enum CompositionEvent {
    CompositionEnabled,
    CompositionPreedit(String, Option<usize>, Option<usize>),
    CompositionCommit(String),
    CompositionDisabled,
}

That I've mentioned on #1497 if you don't have any objects, unfortunately I don't really know much about X11, so it's a bit hard for me to update its code myself.

Also we can name rename PreeditState to IMEEvent, and have

pub enum IMEEvent {
    Enabled,
    Preedit(String, Option<usize>, Option<usize>),
    Commit(String),
    Disabled,
}

So I guess Start and Update should be transformed into Preedit, and End should be transformed into Commit.

Enabled and Disabled should be implemented, and I guess you have that information from X server, at least I can see something like that in xim docs.

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 think you miss Start (or maybe PreeditStart?) event. Other than that, I think it looks fine.

Copy link
Member

Choose a reason for hiding this comment

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

I think you miss Start (or maybe PreeditStart?) event. Other than that, I think it looks fine.

Could you explain why PreeditStart is required? on Wayland for example everything starts with just Preedit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In Wep API, CompositionStart exist in the specification. And in x11, every IME session starts with preedit start event. So, I believe something to tell us when a new IME session starts is necessary.

Copy link
Member

Choose a reason for hiding this comment

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

By start you mean that input method got open or just new input? Since Wayland has a concept of 'Enabled', when user uses its IME, like they opened 'fcitx' or 'ibus' and focused your app. But there's no notion of 'Start', and everything is communicated via 'Preedit' and 'Commit'.

My question was about start, since it looked like Preedit("", None, None) to me.

Copy link
Member

Choose a reason for hiding this comment

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

So, your suggestion is the application can detect the session start by checking the second argument is empty?

But why do you need to detect session start at all? The start is when you've got any IME event.

I mean, I don't understand how end users will handle Start differently to Preedit? Could you give an example where handling of those 2 are different and it makes sense? I get that it's common API for X11 and Web, but it really feels like someone decided to add redundant event that you can mirror with other events.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, I don't have an idea of specific usage for Start event for now, but Start event looks relatively common, so I'm afraid that there is some needs.
But if there is no special use case, it might be OK to combine them.

Copy link
Contributor

@kaiwk kaiwk Dec 1, 2020

Choose a reason for hiding this comment

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

I mean, I don't understand how end users will handle Start differently to Preedit? Could you give an example where handling of those 2 are different and it makes sense?

An example I met before was, I need to know whether I should handle ReceiveCharacter or not. When I get PreeditStart, I can set a flag like isPreediting. If isPreediting is true, I will ignore ReceiveCharacter event.

(However, we can do it in winit though: when preediting, we don't trigger ReceiveCharacter.)

I think it may be useful when user need to do stuff depend on IME state.

Copy link
Member

Choose a reason for hiding this comment

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

If we do preedit we don't need to send receivedchar, since the data is being send via preedit.

Copy link
Contributor

@kaiwk kaiwk Dec 2, 2020

Choose a reason for hiding this comment

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

I'm not sure, but there may be other events in the similar situation. For example, user may also want to ignore KeyboardInput when do preedit (IME will handle arrow keys and backspace, so user may want to ignore them). We can't take into account all the cases I suppose.

#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum IMEEvent {
/// The user enables IME
Enabled,
Copy link
Member

Choose a reason for hiding this comment

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

Does X11 have an event to tell you when you actually have IME running or how to you obtain that information? Also does it tell you when disable happens, since if X11 doesn't have those events they should be issued at some points, since users may only handle IME things after you've actually got those, since IME is user initiated, I guess.

Or it's not the case for X11 and it just always works?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, sorry. This is WIP commit. I think we can get those status with XIMPreeditStateNotifyCallback, so will implement that and test it

@garasubo
Copy link
Contributor Author

I tried to implement Enable/Disable event, but it seems difficult in X11.
I assumed that we could implement them with XNPreeditStateNotifyCallback, but it doesn't work in my environment when I switched the IME.
I investigated some other projects, and found that in Vim, they don't implement since they couldn't find a good way in X11.
Ref: https://groups.google.com/g/vim_dev/c/9j76Z8hd23E?pli=1

@kchibisov do you think we should give up enable/disable event only on X11?

@kchibisov
Copy link
Member

do you think we should give up enable/disable event only on X11?

Have you looked into something like that gtk on that? It seems strange that there's no indication that IME got opened, though, we can just always send enable when creating IME object and send Disabledon close or never send Disabled if it's too complicated to implement now. The point is to send Enabled, if it won't be optimal we won't lose anything, since right now downstream assumes that IME is always enabled.

The thing is that we must send it, but what we use to indicate that could be something not really optimal, if implementing it is something that complicated.

@garasubo
Copy link
Contributor Author

garasubo commented Oct 26, 2020

Yeah, GTK doesn't support enable events either (and won't support XIM at all in GTK4). In X11, we don't destory IME object basically, so the current solution would be never sending Disable event and send Enable event at the beginning.

@kchibisov
Copy link
Member

so the current solution would be never sending Disable event and send Enable event at the beginning.

Looks fine to me, I guess.

@kchibisov
Copy link
Member

I've looked into things again, and I think we can go for now with Disabled/Enabled events tbqh, so just strip them form your impl and we should be good to go.

@garasubo
Copy link
Contributor Author

Sorry for late response. I think I can update the change in this weekend.

@kchibisov
Copy link
Member

Since you've kept enable and removed disable is that correct that there's no way to know that something got disabled? Also, would you mind rebasing the branch?

@garasubo
Copy link
Contributor Author

Is that correct that there's no way to know that something got disabled?

Yes. Also, actually, it doesn't know IME enabled. It just sends enable event when it creates the context object, as we discussed before.

Also, would you mind rebasing the branch?

Sure. Will do it later

@garasubo garasubo force-pushed the composition-event_rename-events branch from 0684ebd to d5220bb Compare November 18, 2020 13:00
@garasubo
Copy link
Contributor Author

Squash and rebased

Copy link
Member

@kchibisov kchibisov left a comment

Choose a reason for hiding this comment

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

You should also fix formatting. After that it should be good to go, I think.

Preedit(String, Option<usize>, Option<usize>),

/// The user completes the current IME session with the value.
Commit(String),
Copy link
Member

Choose a reason for hiding this comment

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

New line here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added

CompositionEnd(String),
pub enum IMEEvent {
/// The user enables IME
Enabled,
Copy link
Member

Choose a reason for hiding this comment

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

New line here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added

src/event.rs Outdated
Comment on lines 640 to 641
/// The value represents a pair of the preedit string and the cursor position.
/// The cursor position is byte-wise indexed.
Copy link
Member

Choose a reason for hiding this comment

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

We should document that the first argument is a cursor begin and second is cursor end. Also if your cursor being and end are equal you should send both of them the same, so in your code you should always send Some(position), Some(position)?

Also, both None should represent a hidden cursor, we should state it as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added those description

event: WindowEvent::Composition(CompositionEvent::CompositionUpdate(
text, position,
)),
event: WindowEvent::IME(IMEEvent::Preedit(text, Some(position), None)),
Copy link
Member

Choose a reason for hiding this comment

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

Also, is there a way to inform that cursor is hidden, thus shouldn't be drawn, if there's such thing we should inform about that via sending None and None?

Suggested change
event: WindowEvent::IME(IMEEvent::Preedit(text, Some(position), None)),
event: WindowEvent::IME(IMEEvent::Preedit(text, Some(position), Some(position))),

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

In X11, I cannot find any event related to hidden cursor.

@kchibisov kchibisov self-requested a review November 21, 2020 19:45
Copy link
Member

@kchibisov kchibisov left a comment

Choose a reason for hiding this comment

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

@garasubo I've decided to rename the event one more time, and call it IME, since event suffix seems redundant here. I've also slightly updated the docs, are you fine with proposed changes?

@@ -89,7 +89,7 @@ extern "C" fn preedit_draw_callback(
.collect()
};
let mut old_text_tail = client_data.text.split_off(chg_range.end);
client_data.text.split_off(chg_range.start);
let _ = client_data.text.split_off(chg_range.start);
Copy link
Member

Choose a reason for hiding this comment

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

This is ignore is intentional right?

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

@kaiwk
Copy link
Contributor

kaiwk commented Nov 22, 2020

I tried to implement Enable/Disable event, but it seems difficult in X11.
I assumed that we could implement them with XNPreeditStateNotifyCallback, but it doesn't work in my environment when I switched the IME.
I investigated some other projects, and found that in Vim, they don't implement since they couldn't find a good way in X11.
Ref: https://groups.google.com/g/vim_dev/c/9j76Z8hd23E?pli=1

@kchibisov do you think we should give up enable/disable event only on X11?

From this guide:

If IME is available on focused elements, we call that state "enabled". If IME is not fully available(i.e., user cannot enable IME), we call this state "disabled".

Could we just simply think that when winit window gets focused, send Enabled and when window loses focus, send Disabled? I didn't find anything similar on Mac, except NSInputContext has activate/deactivate, but it is invoked by the system only.

@kchibisov
Copy link
Member

Could we just simply think that when winit window gets focused, send Enabled and when window loses focus, send Disabled?

The problem is on Wayland it works differently, the system tells you that IME enabled only when you get Enabled event from the system, it's not related to a focus, and can be triggered without focus change, we can model that on X11 around a focus events if it's preferred.

So I wanted to expose this, since if you don't have text-input you won't ever get Enabled, thus there's no point in requesting ime updates all the time.

@garasubo
Copy link
Contributor Author

@kchibisov Thanks. LGTM.

@kchibisov kchibisov merged commit 65cf069 into rust-windowing:composition-event Nov 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants