Skip to content

Commit

Permalink
Merge pull request #763 from Timoses/feature/fix-window-positions
Browse files Browse the repository at this point in the history
[WIP] Allow fixing window position to any side
  • Loading branch information
r0x0r authored Oct 17, 2021
2 parents e68860a + f17f124 commit 9915792
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 27 deletions.
2 changes: 1 addition & 1 deletion webview/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,4 @@ def create_window(title, url=None, html=None, js_api=None, width=800, height=600
def screens():
guilib = initialize()
screens = guilib.get_screens()
return screens
return screens
26 changes: 22 additions & 4 deletions webview/platforms/cef.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from webview.js import dom
from webview import _debug, _user_agent
from webview.util import parse_api_js, default_html, js_bridge_call
from webview.window import FixPoint


sys.excepthook = cef.ExceptHook
Expand Down Expand Up @@ -109,8 +110,25 @@ def initialize(self):
def close(self):
self.browser.CloseBrowser(True)

def resize(self, width, height):
windll.user32.SetWindowPos(self.inner_hwnd, 0, 0, 0, width - 16, height - 38,
def resize(self, width, height, fix_point):

# How much to move to the right
move_x = 0
# How much to move to the bottom
move_y = 0

rect = windll.?.RECT()
rect = windll.user32.GetWindowRect(self.inner_hwnd, rect)

if fix_point & FixPoint.EAST:
current_width = rect.right - rect.left
move_x = current_width - width

if fix_point & FixPoint.SOUTH:
current_height = rect.bottom - rect.top
move_y = current_height - height

windll.user32.SetWindowPos(self.inner_hwnd, 0, move_x, move_y, width - 16, height - 38,
0x0002 | 0x0004 | 0x0010)
self.browser.NotifyMoveOrResizeStarted()

Expand Down Expand Up @@ -288,9 +306,9 @@ def get_current_url(uid):


@_cef_call
def resize(width, height, uid):
def resize(width, height, uid, fix_point):
instance = instances[uid]
instance.resize(width, height)
instance.resize(width, height, fix_point)


@_cef_call
Expand Down
17 changes: 11 additions & 6 deletions webview/platforms/cocoa.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from webview.util import parse_api_js, default_html, js_bridge_call
from webview.js.css import disable_text_select
from webview.screen import Screen
from webview.window import FixPoint

settings = {}

Expand Down Expand Up @@ -475,13 +476,17 @@ def toggle():
AppHelper.callAfter(toggle)
self.is_fullscreen = not self.is_fullscreen

def resize(self, width, height):
def resize(self, width, height, fix_point):
def _resize():
frame = self.window.frame()

# Keep the top left of the window in the same place
frame.origin.y += frame.size.height
frame.origin.y -= height
if fix_point & FixPoint.EAST:
# Keep the right of the window in the same place
frame.origin.x += frame.size.width - width

if fix_point & FixPoint.NORTH:
# Keep the top of the window in the same place
frame.origin.y += frame.size.height - height

frame.size.width = width
frame.size.height = height
Expand Down Expand Up @@ -838,8 +843,8 @@ def _set_on_top():
AppHelper.callAfter(_set_on_top)


def resize(width, height, uid):
BrowserView.instances[uid].resize(width, height)
def resize(width, height, uid, fix_point):
BrowserView.instances[uid].resize(width, height, fix_point)


def minimize(uid):
Expand Down
24 changes: 21 additions & 3 deletions webview/platforms/gtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from webview.util import parse_api_js, default_html, js_bridge_call
from webview.js.css import disable_text_select
from webview.screen import Screen
from webview.window import FixPoint

logger = logging.getLogger('pywebview')

Expand Down Expand Up @@ -286,7 +287,24 @@ def toggle_fullscreen(self):

self.is_fullscreen = not self.is_fullscreen

def resize(self, width, height):
def resize(self, width, height, fix_point):
if fix_point & FixPoint.NORTH and fix_point & FixPoint.WEST:
self.window.set_gravity(Gdk.Gravity.NORTH_WEST)
elif fix_point & FixPoint.NORTH and fix_point & FixPoint.EAST:
self.window.set_gravity(Gdk.Gravity.NORTH_EAST)
elif fix_point & FixPoint.SOUTH and fix_point & FixPoint.EAST:
self.window.set_gravity(Gdk.Gravity.SOUTH_EAST)
elif fix_point & FixPoint.SOUTH and fix_point & FixPoint.WEST:
self.window.set_gravity(Gdk.Gravity.SOUTH_WEST)
elif fix_point & FixPoint.SOUTH:
self.window.set_gravity(Gdk.Gravity.SOUTH)
elif fix_point & FixPoint.NORTH:
self.window.set_gravity(Gdk.Gravity.NORTH)
elif fix_point & FixPoint.WEST:
self.window.set_gravity(Gdk.Gravity.WEST)
elif fix_point & FixPoint.EAST:
self.window.set_gravity(Gdk.Gravity.EAST)

self.window.resize(width, height)

def move(self, x, y):
Expand Down Expand Up @@ -448,9 +466,9 @@ def _set_on_top():
glib.idle_add(_set_on_top)


def resize(width, height, uid):
def resize(width, height, uid, fix_point):
def _resize():
BrowserView.instances[uid].resize(width,height)
BrowserView.instances[uid].resize(width, height, fix_point)
glib.idle_add(_resize)


Expand Down
22 changes: 17 additions & 5 deletions webview/platforms/qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from webview.util import convert_string, default_html, parse_api_js, js_bridge_call
from webview.js.css import disable_text_select
from webview.screen import Screen
from webview.window import FixPoint


logger = logging.getLogger('pywebview')
Expand Down Expand Up @@ -413,7 +414,18 @@ def on_fullscreen(self):

self.is_fullscreen = not self.is_fullscreen

def on_window_size(self, width, height):
def on_window_size(self, width, height, fix_point):
geo = self.geometry()

if fix_point & FixPoint.EAST:
# Keep the right of the window in the same place
geo.setX(geo.x() + geo.width() - width)

if fix_point & FixPoint.SOUTH:
# Keep the top of the window in the same place
geo.setY(geo.y() + geo.height() - height)

self.setGeometry(geo)
self.setFixedSize(width, height)

def on_window_move(self, x, y):
Expand Down Expand Up @@ -506,8 +518,8 @@ def destroy_(self):
def toggle_fullscreen(self):
self.fullscreen_trigger.emit()

def resize_(self, width, height):
self.window_size_trigger.emit(width, height)
def resize_(self, width, height, fix_point):
self.window_size_trigger.emit(width, height, fix_point)

def move_window(self, x, y):
self.window_move_trigger.emit(x, y)
Expand Down Expand Up @@ -672,8 +684,8 @@ def set_on_top(uid, top):
BrowserView.instances[uid].set_on_top(top)


def resize(width, height, uid):
BrowserView.instances[uid].resize_(width, height)
def resize(width, height, uid, fix_point):
BrowserView.instances[uid].resize_(width, height, fix_point)


def move(x, y, uid):
Expand Down
20 changes: 15 additions & 5 deletions webview/platforms/winforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from webview.util import parse_file_type, inject_base_uri
from webview.js import alert
from webview.screen import Screen
from webview.window import FixPoint

try:
import _winreg as winreg # Python 2
Expand Down Expand Up @@ -334,9 +335,18 @@ def _set():
else:
_set()

def resize(self, width, height):
windll.user32.SetWindowPos(self.Handle.ToInt32(), None, self.Location.X, self.Location.Y,
width, height, 64)
def resize(self, width, height, fix_point):

x = self.Location.X
y = self.Location.Y

if fix_point & FixPoint.EAST:
x = x + self.Width - width

if fix_point & FixPoint.SOUTH:
y = y + self.Height - height

windll.user32.SetWindowPos(self.Handle.ToInt32(), None, x, y, width, height, 64)

def move(self, x, y):
SWP_NOSIZE = 0x0001 # Retains the current size
Expand Down Expand Up @@ -588,9 +598,9 @@ def set_on_top(uid, on_top):
window.on_top = on_top


def resize(width, height, uid):
def resize(width, height, uid, fix_point):
window = BrowserView.instances[uid]
window.resize(width, height)
window.resize(width, height, fix_point)


def move(x, y, uid):
Expand Down
18 changes: 15 additions & 3 deletions webview/window.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import inspect
import logging
import os
from enum import Flag, auto
from functools import wraps

from webview.event import Event
Expand Down Expand Up @@ -44,6 +45,13 @@ def _loaded_call(function):
return _api_call(function, 'loaded')


class FixPoint(Flag):
NORTH = auto()
WEST = auto()
EAST = auto()
SOUTH = auto()


class Window:
def __init__(self, uid, title, url, html, width, height, x, y, resizable, fullscreen,
min_size, hidden, frameless, easy_drag, minimized, on_top, confirm_close,
Expand Down Expand Up @@ -234,16 +242,20 @@ def set_window_size(self, width, height):
:param height: desired height of target window
"""
logger.warning('This function is deprecated and will be removed in future releases. Use resize() instead')
self.gui.resize(width, height, self.uid)
self.resize(width, height)

@_shown_call
def resize(self, width, height):
def resize(self, width, height, fix_point=FixPoint.NORTH | FixPoint.WEST):
"""
Resize window
:param width: desired width of target window
:param height: desired height of target window
:param fix_point: Fix window to specified point during resize.
Must be of type FixPoint. Different points can be combined
with bitwise operators.
Example: FixPoint.NORTH | FixPoint.WEST
"""
self.gui.resize(width, height, self.uid)
self.gui.resize(width, height, self.uid, fix_point)

@_shown_call
def minimize(self):
Expand Down

0 comments on commit 9915792

Please sign in to comment.