Comments (34)
Ok, let me see if I'm thinking about this correctly: instead of webview.create_window()
you would do something like mywindow = webview.create_window_multiple()
, so now instead of, for example, webview.load_url()
it would be something like mywindow.load_url()
?
The problem is that in order for that to work, the BrowserView
class shouldn't implement the singleton pattern. So instead of doing BrowserView.instance = self
when we are initializing the BrowserView
, we need to somehow keep track of the number of windows.
Maybe what can be done is instead of having instance
as a class property, use a list called windows
. That way BrowserView.__init__()
can do something like this:
self.windows.append(self)
This way we wouldn't actually need to add a create_window_multiple
function: calling create_window
automatically appends a window to the list, and it return the browser
object so it can be manipulated directly. If you don't want to work with objects, you can just call the module functions like normal. Following this plan, the module functions should access windows[0]
instead of instance
. For example:
def load_url(url):
BrowserView.windows[0].load_url(url)
from pywebview.
Could not be done directly in javascript on the main window? That window could create and handle other windows. The only thing it cannot be done, it to destroy the main windows leaving the other windows open.
from pywebview.
This is indeed a cool feature, pretty useful. I think @cuibonobo's idea is the best
way to implement the backend. Regarding the frontend, I have the same idea as
@cateee's, using HTML/JS
. Thus we don't need to introduce any new API.
I have tried this in Cocoa and it works really smooth. Screenshot:
Yes, that's seven Pywebview instances running in parallel!
It's pretty straight-forward, checkout the multiple-wins-cocoa
branch of my fork
here. On other platforms, I guess the changes to the BrowserView
class could
imitate this Cocoa implementation. Only the ways to capture the HTML/JS
requests
would require reading API docs of the respective frameworks.
I don't know, can we have a try @r0x0r?
from pywebview.
Sounds reasonable. Let's start with your approach and see where it leads from there. One thing that needs to take into account the windowspec string of windows.open function. That way we can set up the properties of a new window from Javascript.
I have cloned your branch into https://github.com/r0x0r/pywebview/tree/multiple-windows-support. Please feel free to contribute pull requests to it.
from pywebview.
The multi-window JS bridge fails on all the platforms. There maybe something wrong with the test.
I fixed debugging on Cocoa. The setting is global for all the opened windows. There is probably no need to make it specific to individual windows.
from pywebview.
This is a good suggestion. One way to do it would be to leave the current API unchanged and introduce an additonal method create_window_multiple (or something like that) that would return a BrowserView object.
This would require unifying the BrowserView objects across platforms and re-thinking a threading model. According to the current model, GUI is run in a main thread and backend logic in a separate daemon thread.
from pywebview.
Yeah, something like this would do a trick. The main obstacle is that GUI frameworks dictate that GUI must be run in a primary thread. So changing a thread model and spawning multiple windows with create_window_multiple in separate threads would not work, unless multiprocessing is used.
What can be done instead is to make use of multiwindow capabilities of each framework. This would require going through documentation of each framework and figuring out how to do it separately for each platform. Ugh.
from pywebview.
I was assuming that would be the case anyway :)
I'm going to try getting this working on a Mac and then add on the other platforms as I start figuring it out.
from pywebview.
This is a neat approach. I have to think it through first, though. One problem with this implementation is that there is no way to control child windows and all the pywebview functions point to the master window. While this is not a problem for file dialogs, it would be nice to have an ability to destroy, change urls and load html for child windows programmatically. One way to solve this problem would be to introduce an optional instance_id parameter to these functions. We would also need a way to obtain ids of opened windows.
@cuibonobo what's your use case for having multiple windows?
from pywebview.
I got pulled to a different project so I haven't had time to get back to this, but my specific use-case is for an application that has a kind of controller window that serves many child document windows. An example of this would be a painting application where the controller window allows you to pick tools and the document windows is where the actual painting happens.
from pywebview.
I should say a multi-windowed UI is a pretty common use case. Front-end
developers naturally expect at least <a target="_blank">
to work in a web page.
Currently it appears as if it's broken. My best intentions were just to fix this, and
I spotted this issue open. Of course pywebview
is not a re-placement for the
browser, but what if someone wants to use it to indeed build a browser? 😉
from pywebview.
@r0x0r Your suggestion is definitely reasonable. So I have been experimenting with
an instance_id
parameter for the API calls. It's working fine under normal use, but
I have spotted some potential bugs.
Still, managing the child windows via JavaScript (open
, location.href
,close
,
etc.) seems to be a better option. The native API should exist, should a user need
them.
from pywebview.
Well it turns out to be a little clumsy. I did it the natural way: use the list indices of
BrowserView.instances
as our instance_id
's, and access each instance via the
usual instances[instance_id]
within the API functions. While it works well, it's not
a good approach as it requires the user to keep track of the number of each window
opened by JS. JS can internally keeps a ref to all windows it opens, but I can't see
any way to translate this to our Python instance_id
.
For now I have settled with a less functional but cleaner solution: route all API calls
to the key window (the one that currently has user focus) instead of the master
window. IMHO this seems to be enough for the requirements. If it sounds good,
feel free to check out my latest commit.
from pywebview.
Great! Meanwhile I hope you try and port it to the other platforms.
from pywebview.
About the windowspec string in Cocoa:
We don't seem to have access to it. In fact we don't even have access to the request
that opens new windows.
But there is no need. We shouldn't care, because Cocoa/WebKit somehow magically
handles the windowspecs automatically. The only drawback is that it supports only
those properties supported by Safari (basically height
,width
, left
, top
; see
Parameter Values -> specs here). Screenshot:
But this is expected behaviour. Can't complain; Cocoa does it for us. 😃
Is the work for multi-window support in other platforms on? I'm focusing on Cocoa
only because I haven't got a Windows machine. Could have helped on Linux, but I
would need to learn GTK/QT from ground up. Let me see if I get time..
from pywebview.
I'm working on multi-window support in GTK. Added basic support, testing.
Not ready for push, there are a couple of bugs. Hope to tackle them soon.
from pywebview.
I briefly took a look at the Windows implementation and it seems that WinForms does not support new window events directly, but instead the NewWindow3 event of Win32 should be used. The problem is that I still haven't managed to call Win32 code from pythonnet (casting interfaces is the root problem). So this might take a while to figure it out.
from pywebview.
Sorry for getting late on this, got busy with other stuff. Nevertheless I had been
working on it occasionally. I should say our original (ambitious) approach turned
out to be more cumbersome than I had imagined. It's a long story; the essence is
I couldn't find a good way to control windows opened by JS from Python. We had
discussed this, and I decided to use the JavaScript window.name
parameter to
address the instances cross-language, but w/o much success, owing to the quirks
with the WebKit API needed to do this. For now, I have dropped my attempts on it.
Instead, I have been trying out a simpler approach lately and it has given me far
better results. The basic idea is to make the create_window
function thread-safe
so that it can be called multiple times via subthreads. create_window
returns a
unique instance id, which can be used to point the API functions to the instances.
I have done the basic implementation and testing on Mac and Linux (both GTK &
Qt); I'm pushing a new multi-window
branch with my work that is also upto date
with master
. I am also deleting the old multiple-windows-support
branch from
upstream as it has grown stale; most of the basic ideas used on it are retained in
the new approach as well. I've maintained a local copy of those commits, in case.
It needs to be tested extensively, @cuibonobo can you spare some minutes and
give some feedback? We also need a Windows implementation @r0x0r 🙂 and
your thoughts?
from pywebview.
Good work, @shivaprsdv ! I gave it a cursory look and the interface looks fine to me, we can go with that. Some minor questions/issues that I could think of
- How about making
instances
a dictionary, as every windows has got its own unique id anyway. This way_get_item
would not be needed - Is there a special relationship between master and child windows in this implementation? E.g. should the program quit when the master window is closed?
- Window naming. Maybe child windows should have more friendly names, like 'child_truncateduuid'. Not sure if window names will be looked by human eyes, but in case they are (as in debugging), it would be nice to have a more friendly name.
- With multiple windows, it would be nice to have windows without chrome, i.e. content only windows with easy move functionality. This is by no means something we should have at this point, but rather something for the future.
It is a big change, so we have to carry on carefully with it. I will give it more thorough testing and will proceed from there.
from pywebview.
Thank you @r0x0r. 🙂 Glad that the approach appealed to you.
Great suggestions as well, I have looked into each:
-
This appealed to me right away, implemented at once (this makes the last
commit useless, so I have rebased it). -
There is currently no special status to the master window (except for its
uid
, of course). The program is set to quit when all windows are closed.
This can be altered with little effort; so we may let the user decide on this
behaviour. I can think of two ways:- Add an appropriate boolean parameter to
webview.config
; or - Give an API method to check if the master window exists at any time.
The latter seems better to me. A
window_exists(uid)
method would be
handy anyway, as you suggested. The user can then do something like:while webview.window_exists('master'): pass # master closed, close all windows, clean up if needed
from a subthread. If the above signature is okay, shall I implement it?
- Add an appropriate boolean parameter to
-
This is something I have felt as well. I'm looking for the best way to
truncate UUIDs. Will do once I find a good solution. -
By a chrome-less window, do you mean a window without a titlebar?
I don't know if such windows are supported on all platforms.
As I have mentioned, this feature solves many other issues as well. So I
think it should be given some priority. More testing and feedback would
definitely help. 👍
from pywebview.
Done implementing 2 and 3 above.
from pywebview.
@shivaprsdv could you rebase this branch? I will start working on it.
from pywebview.
I have merged the latest master
into multi-window
. I also gave the js_api
feature a test run with the multi-window code; it worked pretty smoothly, no
thing there seems to have broken this. You may build on it straightaway. I hope
we can finish with this before another train of commits on master. 🙂
from pywebview.
I have pushed the WinForms implementation and some multi-window tests (more to come). @shivaprsdv Could you implement the multi-window support for the rest of platforms? I have merged the latest master into the multi-window branch.
Also refactored tests, which hopefully makes them more robust.
from pywebview.
Do we have a misunderstanding? Because I had already implemented multi-window
support on the other platforms. 😃
Anyway I have looked into the changes you have made and made some updates, and
a bit of cleaning up as well. Two things to do:
-
Currently the multi-window test is not running properly. The issue is, there is
no destroy event set for the child windows; I have to manually close them. Can
you fix this? I tried adding the uid param to thedestroy_window
function in
utils.py
, but couldn't find the best way to proceed from there. -
As it is almost merge-ready, we need to add documentation for multi-window
support. Should I write it?
from pywebview.
Sorry, I meant the multi-window support for set_title
. I merged the set-title branch after your changes.
- On Windows the default behavior is to quit the program when the master window is closed. I will change it.
- Please go ahead.
from pywebview.
When opening a new window on Cocoa, it places it in exactly the same position as the original window. To prevent obscuring, there should be a offset for new windows.
Specifying window position should probably be added at some point, but a default offset should be enough for now.
from pywebview.
Pushed. I had done it in the old branch, can't remember why I left it out from this.
from pywebview.
Nice one.
I've pushed a js bridge multi-window test. I haven't managed to get it passed on Cocoa. assert for the seconds window fails. Another problem is that setting debug to True on both windows freezes the second window.
I am yet to test it on other platforms.
from pywebview.
I think it has got to do with our old problem of closing child windows: I now have
to close the windows manually again, and the test pass. I suggest you look into
whether destroy_window calls are done properly.
from pywebview.
Cocoa implementation is not thread safe. In particular load_event is a class attribute, when it should be an instance attribute. Currently the multi window js bridge test hangs due infinite waiting for load_event in evaluate_js in the second window. There are also considerable lags with every evaluate_js call, I suspect that webview_ready is timing out, instead of returning right away.
Other than that, refactored assert_js
, as well as implemented conversion to Python types of values returned by evaluate_js
in Cocoa. It also occurred to me that Javascript objects should be converted to Python dicts, but this is a job for another time.
from pywebview.
I have fixed Cocoa among other changes. Test seem to pass, apart from random fails on Python2/GTK. I could not reproduce fails locally, so let it be for the time being. It seems that the test infrastructure requires an overhaul.
Apart from the documentation, this is ready for merge. What do you think @shivaprsdv?
from pywebview.
Great! Especially good to see tests passing on Cocoa, after some time. I have
pushed the documentation; I tried to keep it to the minimum, feel free to modify
it as you find appropriate.
BTW it would be useful to expose the uid
of the window to the JS API. But this
means we need to create the API object regardless of the user passing a js_api
parameter. Only if it is a light task, could be done before merge. Otherwise let's
keep it for post-merge. Everything else looks fine. 👍
from pywebview.
@cuibonobo Starting from your idea, pywebview now have full multiple windows
support. Please check it out. And thanks for your input! 🙂
from pywebview.
Related Issues (20)
- [QUESTION] Is there a way to go back without calling JavaScript using 4.4.1? HOT 5
- Enable Spell Check without Requiring webview.start(debug=True) HOT 4
- Issue with pywebview Version Upgrade from 4.4.1 to 5.0.5 HOT 2
- Whether to support webgal HOT 4
- how to build android apk HOT 7
- webview tag in pywebview HOT 6
- Support transparency with blurred background. HOT 1
- Drag Area cannot be initialized by a script after page loads. HOT 3
- RangeError: Maximum call stack size exceeded. HOT 7
- Frameless window can not be minimized by clicking its taskbar button HOT 4
- Use window inside of tkinter HOT 4
- iframe cannot call Python HOT 1
- Nuitka support HOT 7
- [WIN] Folder Dialog - New folder is renamed with a delay.
- [Maybe bug] The todos app crashed immediately after I run "buildozer -v android debug deploy run" HOT 13
- google account logout after close the pywebview window HOT 4
- any way to edit the response headers (or somehow disable X-Frame-Options)? HOT 7
- How do I unround the corners of a borderless window?
- [QUESTION] Can pywebview be embedded anywhere? HOT 2
- How can we lift the CORS restrictions in pywebview? HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pywebview.