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

Unable to remove main window in multi window Application #99

Closed
Exidex opened this issue Dec 2, 2024 · 17 comments
Closed

Unable to remove main window in multi window Application #99

Exidex opened this issue Dec 2, 2024 · 17 comments

Comments

@Exidex
Copy link

Exidex commented Dec 2, 2024

In multi_window Application it is not currently possible to remove main window. Main window seems to have id 0 if start mode is background code or is otherwise random. In iced 0.13 window::Id::MAIN was removed in favor of always specifying id for new windows. And window::Id::unique() starts at 1. Additionally in daemon mode (new multi_window replacement) application starts without any windows. Also there is no way to get an id of a window in iced_layershell, which is possible in iced 0.13

@Decodetalkers
Copy link
Collaborator

I do not quite know how to fix it... because seems the main wl_surface cannot be destroyed then the iced compositor will also been destroyed.. a bit hard for me.. what is the usecase?

@Exidex
Copy link
Author

Exidex commented Dec 4, 2024

@Decodetalkers thanks for such fast changes

The use case is showing and hiding window of application launcher. Application is usually started without the main window when DE/WM starts and then window is shown by pressing global shortcut.

I have been testing your changes which added iced_layershell::build_pattern::daemon and it seems to work ok with no windows.

But I am facing a unwrap panic here, when removing a window

ev.remove_shell(option_id.unwrap());

Also, possibly unrelated, for some reason the created window only shows background color with nothing being rendered, not quite sure if it a problem on my side. here is a migration to iced-layershell commit if you want to take a look: project-gauntlet/gauntlet@9a57c47

Found the issue, the window id specified with LayershellCustomActionsWithInfo::NewLayerShell does not match the window id passed to daemon's view function. If window is created with id == 1, id == 2 will be passed to view function

@Decodetalkers
Copy link
Collaborator

Decodetalkers commented Dec 5, 2024

@Decodetalkers thanks for such fast changes

The use case is showing and hiding window of application launcher. Application is usually started without the main window when DE/WM starts and then window is shown by pressing global shortcut.

I have been testing your changes which added iced_layershell::build_pattern::daemon and it seems to work ok with no windows.

But I am facing a unwrap panic here, when removing a window

ev.remove_shell(option_id.unwrap());

Also, possibly unrelated, for some reason the created window only shows background color with nothing being rendered, not quite sure if it a problem on my side. here is a migration to iced-layershell commit if you want to take a look: project-gauntlet/gauntlet@9a57c47

Found the issue, the window id specified with LayershellCustomActionsWithInfo::NewLayerShell does not match the window id passed to daemon's view function. If window is created with id == 1, id == 2 will be passed to view function

The problem is that we cannot know the main id.. and for iced_layershell, the main id may be more than one. Then this time we cannot know if the id is the main window. Possible solution is to send close request from the widget in view, where they know the id

for other manually created windows, there are functions to mark their identities, and we can get their id from the identities, but for main windows, it seems a little difficult.. should the main id be also stored? and another optional function to allow user to get the main windows?

@Decodetalkers
Copy link
Collaborator

#101 please try this pr. now I add the ability to record the mainwindow ids, now it is possible for you to know the id of mainwindow

@Decodetalkers
Copy link
Collaborator

In multi_window Application it is not currently possible to remove main window. Main window seems to have id 0 if start mode is background code or is otherwise random. In iced 0.13 window::Id::MAIN was removed in favor of always specifying id for new windows. And window::Id::unique() starts at 1. Additionally in daemon mode (new multi_window replacement) application starts without any windows. Also there is no way to get an id of a window in iced_layershell, which is possible in iced 0.13

by the way, how can iced get the mainwindow id?

@Exidex
Copy link
Author

Exidex commented Dec 5, 2024

please try this pr

I am not quite sure how I would need use that

by the way, how can iced get the mainwindow id?

Basically this is the difference between iced::daemon and iced::application

If you are using iced::application it means you will always have at least one window, if you close the last window whole program exits. All functions (title, update, view) passed to iced::application do not have id parameters because you will never need it for simple applications. But you can still get the id using get_oldest and get_latest task actions.

When using iced::daemon application starts without any windows and does not exit when there is no windows left. You can use window::open to create new window, this function returns (Id, Task<Id>) and you can store the Id it returns. Additionally all functions (title, update, view) passed to iced::daemon have window::Id parameter which allows to have different behavior depending on window (including different titles per window)

@Exidex
Copy link
Author

Exidex commented Dec 5, 2024

Either way, it is already possible to get window id with iced_layershell::build_pattern::daemon.

I just need you to fix:

  • Panic when removing a window
  • Fix window id that is passed to view function so it will match the window id passed into NewLayerShell action
  • Add window id to daemon NameSpace function

@Decodetalkers
Copy link
Collaborator

Decodetalkers commented Dec 6, 2024

Either way, it is already possible to get window id with iced_layershell::build_pattern::daemon.

I just need you to fix:

  • Panic when removing a window
  • Fix window id that is passed to view function so it will match the window id passed into NewLayerShell action
  • Add window id to daemon NameSpace function

Emm.

If you meet removing window panic, that means you have passed an id does not exist

I think that NewLayerShell won't accept any id, you can only receive the id by registering the function of set_id_info, and use the info to find the id, and also you need to listen on remove_id functionhttps://github.com/waycrate/exwlshelleventloop/blob/master/iced_examples/counter_mulit_pattern/src/main.rs#L99-L110

Why is it needed to pass id to the namespace function?

by the way, have you register the functions in the way likes

https://github.com/waycrate/exwlshelleventloop/blob/master/iced_examples/counter_mulit_pattern/src/main.rs#L99-L110

This allows you to get the registered id which match the passed WindowInfo, now the pr #101 allow you with the same way to get the id of MainWindow, just need to tell iced_layershell which field of enum is the mainwindow, and iced_layershell will return that id for you

@Decodetalkers
Copy link
Collaborator

And that pr allows you to mark one field of the enum to accept the creating and removing event of main windows. I think that will meet your needs. The only thing you need to do is just register the set_id_info and remove_id

@Decodetalkers
Copy link
Collaborator

Decodetalkers commented Dec 6, 2024

Haa... I see.. that LayershellCustomActionsWithId, this id means the id of the sender, not the id to be created... sorry for that, you had better to use the macro to impl it will be better.. the id in LayershellCustionActionWidhIdAndInfo, is used to change the state of the already existed layershell. It is used to change the attribute of the layershell, like layer, anchor, margin, so when you create a new layershell, the id is still not exist, so in this case , the id in LayershellCustionActionWidhIdAndInfo is useless. so I recommand you to use the macro, not impl the try_into trait yourself

and you need to register a WindowInfo, to mark the type of layershell.. sorry for your confuse, because I write a such bad document

@Exidex
Copy link
Author

Exidex commented Dec 6, 2024

Ok, I see.

The problem is that the api style doesn't match to usual iced. It is needlessly complicated to have callback-style api to get id of the windows. Why would I need to implement all id_info, set_id_info and remove_id_info if i could just pass my id to the create new layer message and store it my self (like already implemented in project-gauntlet/gauntlet@9a57c47) it is a lot less code and it is how it is done in usual iced and in PopOS's fork with layer shell

Why is it needed to pass id to the namespace function?

same reason why there is id in iced::deamon title. to have different namespace based on which window it is for

@Decodetalkers
Copy link
Collaborator

Decodetalkers commented Dec 7, 2024

Ok, I see.

The problem is that the api style doesn't match to usual iced. It is needlessly complicated to have callback-style api to get id of the windows. Why would I need to implement all id_info, set_id_info and remove_id_info if i could just pass my id to the create new layer message and store it my self (like already implemented in project-gauntlet/gauntlet@9a57c47) it is a lot less code and it is how it is done in usual iced and in PopOS's fork with layer shell

Why is it needed to pass id to the namespace function?

same reason why there is id in iced::deamon title. to have different namespace based on which window it is for

Namespace is not a title, it is just used to tell wm what this program is. And a program just owned one namespace.

Because we need to mark different layershell, get their identity. You can take a look at that example

As I already have told you. You should not implement the tryInto trait yourself, but should use the macro. The id used in that action just means the sender, when you want to create a new layershell, the sender will not exist, so in this case that place it is useless. So I recommend you to use that macro. It will add proper field to that enum, without useless fields.

@Decodetalkers
Copy link
Collaborator

Decodetalkers commented Dec 7, 2024

Ok, I see.

The problem is that the api style doesn't match to usual iced. It is needlessly complicated to have callback-style api to get id of the windows. Why would I need to implement all id_info, set_id_info and remove_id_info if i could just pass my id to the create new layer message and store it my self (like already implemented in project-gauntlet/gauntlet@9a57c47) it is a lot less code and it is how it is done in usual iced and in PopOS's fork with layer shell

Why is it needed to pass id to the namespace function?

same reason why there is id in iced::deamon title. to have different namespace based on which window it is for

Ha.. I have already understand your problem..

the window::open in iced return the window::Action::Open, which I cannot add mine part for it. my lib can just send the Messages, .. and .. Yes, I can use the id of the sender to create the layershell, instead use the window::Id::unique to create one.. you are right. then it will be a little vague for the usage of the id.. it can be the sender, or the id of the new layershell..

For another thing about why I create the WindowInfo.. because the layershell is not created just after the messaged be sended, sometimes maybe with multi times of clicked, it will create more than once layershell, so it need to be controlled in some enum, so I create the WindowInfo..

Above all, I will create a pr for it.. then you can take a try

update

Emm.. seems not good.. only if the info contains the message of id.. because the logic of this crate cannot know the id before the layershell being created, the only thing it has is just the WindowInfo, only when the WindowInfo has the message of Id, then it can be used, but then I need to induced another trait...

After all, this lib cannot do the thing like what iced::window::open do, because it cannot add extra event to iced::Event

@Decodetalkers
Copy link
Collaborator

Ok, after thinking about this thing... this design is a mistake.. but now I do not have enough energy to change it ..

@Decodetalkers
Copy link
Collaborator

Decodetalkers commented Dec 8, 2024

done #103

but I still keep remove_id, because if when invoke remove window, this time window still not been removed, that will cause render problems

@Decodetalkers
Copy link
Collaborator

done, now you can try the new rc version.. I think that will solve your problem

@Exidex
Copy link
Author

Exidex commented Dec 8, 2024

Works now as intended, thanks a lot!

@Exidex Exidex closed this as completed Dec 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants