From 5fa2e479926a1556fe505bd22c8e48378842f297 Mon Sep 17 00:00:00 2001
From: Avasam
Date: Thu, 11 Nov 2021 01:16:18 -0500
Subject: [PATCH 1/4] check before PrintWindow
---
src/capture_windows.py | 45 +++++++++++++++++++++++++++++-------------
1 file changed, 31 insertions(+), 14 deletions(-)
diff --git a/src/capture_windows.py b/src/capture_windows.py
index d6798ed6..e2469d93 100644
--- a/src/capture_windows.py
+++ b/src/capture_windows.py
@@ -1,13 +1,14 @@
from ctypes import windll
-from ctypes.wintypes import LONG, RECT
+from ctypes.wintypes import LONG, RECT, HBITMAP
+from typing import Dict
from win32 import win32gui
import numpy as np
import win32ui
import win32con
-import numpy as np
# This is an undocumented nFlag value for PrintWindow
PW_RENDERFULLCONTENT = 0x00000002
+accelerated_windows: Dict[int, bool] = {}
def capture_region(hwnd: int, rect: RECT):
@@ -20,26 +21,42 @@ def capture_region(hwnd: int, rect: RECT):
@return: The image of the region in the window in BGRA format
"""
+ is_accelerated_window = accelerated_windows.get(hwnd)
+
+ # The window type is not yet known, let's find out!
+ if is_accelerated_window is None:
+ # We need to get the image at least once to check if it's full black
+ image = __get_image(hwnd, rect, False)
+ # TODO check for first non-black pixel, no need to iterate through the whole image
+ is_accelerated_window = not np.count_nonzero(image)
+ accelerated_windows[hwnd] = is_accelerated_window
+ return __get_image(hwnd, rect, True) if is_accelerated_window else image
+
+ return __get_image(hwnd, rect, is_accelerated_window)
+
+
+def __get_image(hwnd: int, rect: RECT, printWindow=False):
width: LONG = rect.right - rect.left
height: LONG = rect.bottom - rect.top
-
- windowDC = win32gui.GetWindowDC(hwnd)
+ windowDC: int = win32gui.GetWindowDC(hwnd)
dcObject = win32ui.CreateDCFromHandle(windowDC)
+
+ # Causes a 10-15x performance drop. But allows recording hardware accelerated windows
+ if (printWindow):
+ windll.user32.PrintWindow(hwnd, dcObject.GetSafeHdc(), PW_RENDERFULLCONTENT)
+
compatibleDC = dcObject.CreateCompatibleDC()
- bmp = win32ui.CreateBitmap()
- bmp.CreateCompatibleBitmap(dcObject, width, height)
- compatibleDC.SelectObject(bmp)
+ bitmap: HBITMAP = win32ui.CreateBitmap()
+ bitmap.CreateCompatibleBitmap(dcObject, width, height)
+ compatibleDC.SelectObject(bitmap)
compatibleDC.BitBlt((0, 0), (width, height), dcObject, (rect.left, rect.top), win32con.SRCCOPY)
- # Force render full content through PrintWindow. Workaround to capture hardware accelerated windows
- windll.user32.PrintWindow(hwnd, dcObject.GetSafeHdc(), PW_RENDERFULLCONTENT)
-
- img: np._BufferType = np.frombuffer(bmp.GetBitmapBits(True), dtype='uint8')
- img.shape = (height, width, 4)
+ image: np._BufferType = np.frombuffer(bitmap.GetBitmapBits(True), dtype='uint8')
+ image.shape = (height, width, 4)
dcObject.DeleteDC()
compatibleDC.DeleteDC()
win32gui.ReleaseDC(hwnd, windowDC)
- win32gui.DeleteObject(bmp.GetHandle())
+ win32gui.DeleteObject(bitmap.GetHandle())
- return img
+ return image
From 5a014131f9e46b6d36b99b68fde384470e20de11 Mon Sep 17 00:00:00 2001
From: Avasam
Date: Thu, 11 Nov 2021 13:26:20 -0500
Subject: [PATCH 2/4] Check is_windows_11 for PrintWindow
---
src/capture_windows.py | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/capture_windows.py b/src/capture_windows.py
index e2469d93..d8065416 100644
--- a/src/capture_windows.py
+++ b/src/capture_windows.py
@@ -2,6 +2,7 @@
from ctypes.wintypes import LONG, RECT, HBITMAP
from typing import Dict
from win32 import win32gui
+import sys
import numpy as np
import win32ui
import win32con
@@ -9,6 +10,7 @@
# This is an undocumented nFlag value for PrintWindow
PW_RENDERFULLCONTENT = 0x00000002
accelerated_windows: Dict[int, bool] = {}
+is_windows_11 = sys.getwindowsversion().build >= 22000
def capture_region(hwnd: int, rect: RECT):
@@ -21,7 +23,9 @@ def capture_region(hwnd: int, rect: RECT):
@return: The image of the region in the window in BGRA format
"""
- is_accelerated_window = accelerated_windows.get(hwnd)
+ # Windows 11 has some jank, and we're not ready to fully investigate it
+ # for now let's ensure it works at the cost of performance
+ is_accelerated_window = is_windows_11 or accelerated_windows.get(hwnd)
# The window type is not yet known, let's find out!
if is_accelerated_window is None:
@@ -35,14 +39,14 @@ def capture_region(hwnd: int, rect: RECT):
return __get_image(hwnd, rect, is_accelerated_window)
-def __get_image(hwnd: int, rect: RECT, printWindow=False):
+def __get_image(hwnd: int, rect: RECT, print_window=False):
width: LONG = rect.right - rect.left
height: LONG = rect.bottom - rect.top
windowDC: int = win32gui.GetWindowDC(hwnd)
dcObject = win32ui.CreateDCFromHandle(windowDC)
# Causes a 10-15x performance drop. But allows recording hardware accelerated windows
- if (printWindow):
+ if (print_window):
windll.user32.PrintWindow(hwnd, dcObject.GetSafeHdc(), PW_RENDERFULLCONTENT)
compatibleDC = dcObject.CreateCompatibleDC()
From d63f050d707e827a7f023f36d0deeb4ba8d51d85 Mon Sep 17 00:00:00 2001
From: Austin <37423484+Toufool@users.noreply.github.com>
Date: Thu, 11 Nov 2021 21:11:47 -0500
Subject: [PATCH 3/4] correct Windows 11 check
---
src/capture_windows.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/capture_windows.py b/src/capture_windows.py
index d8065416..b0a9c84f 100644
--- a/src/capture_windows.py
+++ b/src/capture_windows.py
@@ -3,6 +3,8 @@
from typing import Dict
from win32 import win32gui
import sys
+from packaging import version
+import platform
import numpy as np
import win32ui
import win32con
@@ -10,7 +12,7 @@
# This is an undocumented nFlag value for PrintWindow
PW_RENDERFULLCONTENT = 0x00000002
accelerated_windows: Dict[int, bool] = {}
-is_windows_11 = sys.getwindowsversion().build >= 22000
+is_windows_11 = version.parse(platform.version()) >= version.parse("10.0.22000")
def capture_region(hwnd: int, rect: RECT):
From cada37b5d1db0969448af6e6adbc40ca6b7a5964 Mon Sep 17 00:00:00 2001
From: Austin <37423484+Toufool@users.noreply.github.com>
Date: Thu, 11 Nov 2021 21:12:18 -0500
Subject: [PATCH 4/4] Change Version to 1.5.2
---
src/about.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/about.py b/src/about.py
index 93f90bfe..66bd36f1 100644
--- a/src/about.py
+++ b/src/about.py
@@ -59,7 +59,7 @@ def retranslateUi(self, aboutAutoSplitWidget):
aboutAutoSplitWidget.setWindowTitle(_translate("aboutAutoSplitWidget", "About AutoSplit", None))
self.okButton.setText(_translate("aboutAutoSplitWidget", "OK", None))
self.createdbyLabel.setText(_translate("aboutAutoSplitWidget", "Created by Toufool and Faschz
", None))
- self.versionLabel.setText(_translate("aboutAutoSplitWidget", "Version: 1.5.1", None))
+ self.versionLabel.setText(_translate("aboutAutoSplitWidget", "Version: 1.5.2", None))
self.donatetextLabel.setText(_translate("aboutAutoSplitWidget", "If you enjoy using this program, please\n"
" consider donating. Thank you!", None))
self.donatebuttonLabel.setText(_translate("aboutAutoSplitWidget", "
", None))