mirror of
https://github.com/greenshot/greenshot
synced 2025-08-19 13:10:00 -07:00
Fixed a visibility check on Apps and added the gutter! The "Snapped Desktop" is still missing and if this is visible it won't go away...
git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2457 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
parent
141da5e724
commit
8b0253bdf9
2 changed files with 68 additions and 70 deletions
|
@ -896,14 +896,14 @@ namespace Greenshot.Helpers {
|
||||||
|
|
||||||
#region capture with feedback
|
#region capture with feedback
|
||||||
private void CaptureWithFeedback() {
|
private void CaptureWithFeedback() {
|
||||||
using (CaptureForm captureForm = new CaptureForm(capture, windows)) {
|
// Added check for metro (Modern UI) apps, which might be maximized and cover the screen.
|
||||||
// Added check for metro (Modern UI) apps, which might be maximized and cover the screen.
|
// as they don't want to
|
||||||
// as they don't want to
|
foreach(WindowDetails app in WindowDetails.GetMetroApps()) {
|
||||||
foreach(WindowDetails app in WindowDetails.GetMetroApps()) {
|
if (app.Maximised) {
|
||||||
if (app.Maximised) {
|
app.HideApp();
|
||||||
app.HideApp();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
using (CaptureForm captureForm = new CaptureForm(capture, windows)) {
|
||||||
DialogResult result = captureForm.ShowDialog();
|
DialogResult result = captureForm.ShowDialog();
|
||||||
if (result == DialogResult.OK) {
|
if (result == DialogResult.OK) {
|
||||||
selectedCaptureWindow = captureForm.SelectedCaptureWindow;
|
selectedCaptureWindow = captureForm.SelectedCaptureWindow;
|
||||||
|
|
|
@ -162,6 +162,8 @@ namespace GreenshotPlugin.Core {
|
||||||
public class WindowDetails : IEquatable<WindowDetails>{
|
public class WindowDetails : IEquatable<WindowDetails>{
|
||||||
private const string METRO_WINDOWS_CLASS = "Windows.UI.Core.CoreWindow";
|
private const string METRO_WINDOWS_CLASS = "Windows.UI.Core.CoreWindow";
|
||||||
private const string METRO_APPLAUNCHER_CLASS = "ImmersiveLauncher";
|
private const string METRO_APPLAUNCHER_CLASS = "ImmersiveLauncher";
|
||||||
|
private const string METRO_GUTTER_CLASS = "ImmersiveGutter";
|
||||||
|
|
||||||
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(WindowDetails));
|
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(WindowDetails));
|
||||||
private static Dictionary<string, List<string>> classnameTree = new Dictionary<string, List<string>>();
|
private static Dictionary<string, List<string>> classnameTree = new Dictionary<string, List<string>>();
|
||||||
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
|
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
|
||||||
|
@ -201,6 +203,13 @@ namespace GreenshotPlugin.Core {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool isGutter {
|
||||||
|
get {
|
||||||
|
return METRO_GUTTER_CLASS.Equals(ClassName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool isAppLauncher {
|
public bool isAppLauncher {
|
||||||
get {
|
get {
|
||||||
return METRO_APPLAUNCHER_CLASS.Equals(ClassName);
|
return METRO_APPLAUNCHER_CLASS.Equals(ClassName);
|
||||||
|
@ -641,22 +650,12 @@ namespace GreenshotPlugin.Core {
|
||||||
public bool Maximised {
|
public bool Maximised {
|
||||||
get {
|
get {
|
||||||
if (isApp) {
|
if (isApp) {
|
||||||
Rectangle windowRectangle = WindowRectangle;
|
if (Visible) {
|
||||||
foreach (Screen screen in Screen.AllScreens) {
|
Rectangle windowRectangle = WindowRectangle;
|
||||||
if (screen.Bounds.Contains(windowRectangle)) {
|
foreach (Screen screen in Screen.AllScreens) {
|
||||||
if (windowRectangle.Equals(screen.Bounds)) {
|
if (screen.Bounds.Contains(windowRectangle)) {
|
||||||
// Fullscreen, it's "visible" when AppVisibilityOnMonitor says yes
|
if (windowRectangle.Equals(screen.Bounds)) {
|
||||||
// Although it might be the other App, this is not "very" important
|
return true;
|
||||||
RECT rect = new RECT(screen.Bounds);
|
|
||||||
IntPtr monitor = User32.MonitorFromRect(ref rect, User32.MONITOR_DEFAULTTONULL);
|
|
||||||
if (monitor != IntPtr.Zero) {
|
|
||||||
if (appVisibility != null) {
|
|
||||||
MONITOR_APP_VISIBILITY monitorAppVisibility = appVisibility.GetAppVisibilityOnMonitor(monitor);
|
|
||||||
LOG.DebugFormat("App {0} visible: {1} on {2}", Text, monitorAppVisibility, screen.Bounds);
|
|
||||||
if (monitorAppVisibility == MONITOR_APP_VISIBILITY.MAV_APP_VISIBLE) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -690,9 +689,31 @@ namespace GreenshotPlugin.Core {
|
||||||
Rectangle windowRectangle = WindowRectangle;
|
Rectangle windowRectangle = WindowRectangle;
|
||||||
foreach (Screen screen in Screen.AllScreens) {
|
foreach (Screen screen in Screen.AllScreens) {
|
||||||
if (screen.Bounds.Contains(windowRectangle)) {
|
if (screen.Bounds.Contains(windowRectangle)) {
|
||||||
return true;
|
if (windowRectangle.Equals(screen.Bounds)) {
|
||||||
|
// Fullscreen, it's "visible" when AppVisibilityOnMonitor says yes
|
||||||
|
// Although it might be the other App, this is not "very" important
|
||||||
|
RECT rect = new RECT(screen.Bounds);
|
||||||
|
IntPtr monitor = User32.MonitorFromRect(ref rect, User32.MONITOR_DEFAULTTONULL);
|
||||||
|
if (monitor != IntPtr.Zero) {
|
||||||
|
if (appVisibility != null) {
|
||||||
|
MONITOR_APP_VISIBILITY monitorAppVisibility = appVisibility.GetAppVisibilityOnMonitor(monitor);
|
||||||
|
//LOG.DebugFormat("App {0} visible: {1} on {2}", Text, monitorAppVisibility, screen.Bounds);
|
||||||
|
if (monitorAppVisibility == MONITOR_APP_VISIBILITY.MAV_APP_VISIBLE) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Is only partly on the screen, when this happens the app is allways visible!
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (isGutter) {
|
||||||
|
// gutter is only made available when it's visible
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (isAppLauncher) {
|
if (isAppLauncher) {
|
||||||
return IsAppLauncherVisible;
|
return IsAppLauncherVisible;
|
||||||
|
@ -760,7 +781,8 @@ namespace GreenshotPlugin.Core {
|
||||||
GetWindowRect(out windowRect);
|
GetWindowRect(out windowRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!HasParent && (!isApp && Maximised)) {
|
// Correction for maximized windows, only if it's not an app
|
||||||
|
if (!HasParent && !isApp && Maximised) {
|
||||||
Size size = Size.Empty;
|
Size size = Size.Empty;
|
||||||
GetBorderSize(out size);
|
GetBorderSize(out size);
|
||||||
windowRect = new Rectangle(windowRect.X + size.Width, windowRect.Y + size.Height, windowRect.Width - (2 * size.Width), windowRect.Height - (2 * size.Height));
|
windowRect = new Rectangle(windowRect.X + size.Width, windowRect.Y + size.Height, windowRect.Width - (2 * size.Width), windowRect.Height - (2 * size.Height));
|
||||||
|
@ -1522,11 +1544,30 @@ namespace GreenshotPlugin.Core {
|
||||||
/// <returns>List<WindowDetails> with visible metro apps</returns>
|
/// <returns>List<WindowDetails> with visible metro apps</returns>
|
||||||
public static List<WindowDetails> GetMetroApps() {
|
public static List<WindowDetails> GetMetroApps() {
|
||||||
List<WindowDetails> metroApps = new List<WindowDetails>();
|
List<WindowDetails> metroApps = new List<WindowDetails>();
|
||||||
|
//string[] wcs = {"ImmersiveGutter", "Snapped Desktop", "ImmersiveBackgroundWindow","ImmersiveLauncher","Windows.UI.Core.CoreWindow","ApplicationManager_ImmersiveShellWindow","SearchPane","MetroGhostWindow","EdgeUiInputWndClass", "NativeHWNDHost", "Shell_CharmWindow"};
|
||||||
|
//List<WindowDetails> specials = new List<WindowDetails>();
|
||||||
|
//foreach(string wc in wcs) {
|
||||||
|
// IntPtr wcHandle = User32.FindWindow(null, null);
|
||||||
|
// while (wcHandle != IntPtr.Zero) {
|
||||||
|
// WindowDetails special = new WindowDetails(wcHandle);
|
||||||
|
// if (special.WindowRectangle.Left >= 1920 && special.WindowRectangle.Size != Size.Empty) {
|
||||||
|
// specials.Add(special);
|
||||||
|
// LOG.DebugFormat("Found special {0} : {1} at {2} visible: {3} {4} {5}", special.ClassName, special.Text, special.WindowRectangle, special.Visible, special.ExtendedWindowStyle, special.WindowStyle);
|
||||||
|
// }
|
||||||
|
// wcHandle = User32.FindWindowEx(IntPtr.Zero, wcHandle, null, null);
|
||||||
|
// };
|
||||||
|
//}
|
||||||
IntPtr nextHandle = User32.FindWindow(METRO_WINDOWS_CLASS, null);
|
IntPtr nextHandle = User32.FindWindow(METRO_WINDOWS_CLASS, null);
|
||||||
while (nextHandle != IntPtr.Zero) {
|
while (nextHandle != IntPtr.Zero) {
|
||||||
WindowDetails metroApp = new WindowDetails(nextHandle);
|
WindowDetails metroApp = new WindowDetails(nextHandle);
|
||||||
metroApps.Add(metroApp);
|
metroApps.Add(metroApp);
|
||||||
LOG.DebugFormat("Found metro app {0}", metroApp.Text);
|
// Check if we have a gutter!
|
||||||
|
if (metroApp.Visible && !metroApp.Maximised) {
|
||||||
|
IntPtr gutterHandle = User32.FindWindow(METRO_GUTTER_CLASS, null);
|
||||||
|
if (gutterHandle != IntPtr.Zero) {
|
||||||
|
metroApps.Add(new WindowDetails(gutterHandle));
|
||||||
|
}
|
||||||
|
}
|
||||||
nextHandle = User32.FindWindowEx(IntPtr.Zero, nextHandle, METRO_WINDOWS_CLASS, null);
|
nextHandle = User32.FindWindowEx(IntPtr.Zero, nextHandle, METRO_WINDOWS_CLASS, null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1568,7 +1609,6 @@ namespace GreenshotPlugin.Core {
|
||||||
if (!window.Visible && !window.Iconic) {
|
if (!window.Visible && !window.Iconic) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
LOG.DebugFormat("Text {0}", window.Text);
|
|
||||||
windows.Add(window);
|
windows.Add(window);
|
||||||
}
|
}
|
||||||
return windows;
|
return windows;
|
||||||
|
@ -1610,49 +1650,7 @@ namespace GreenshotPlugin.Core {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sort the list of WindowDetails according Z-Order, all not found "windows" come at the end
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="hWndParent">IntPtr of the parent</param>
|
|
||||||
/// <param name="windows">List of windows to sort</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static List<WindowDetails> SortByZOrder(IntPtr hWndParent, List<WindowDetails> windows) {
|
|
||||||
List<WindowDetails> sortedWindows = new List<WindowDetails>();
|
|
||||||
Dictionary<IntPtr, WindowDetails> allWindows = new Dictionary<IntPtr, WindowDetails>();
|
|
||||||
foreach(WindowDetails window in windows) {
|
|
||||||
if (!allWindows.ContainsKey(window.Handle)) {
|
|
||||||
allWindows.Add(window.Handle, window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Sort by Z-Order, from top to bottom
|
|
||||||
for(IntPtr hWnd = User32.GetTopWindow(hWndParent); hWnd!=IntPtr.Zero; hWnd = User32.GetWindow(hWnd, GetWindowCommand.GW_HWNDNEXT)) {
|
|
||||||
if (allWindows.ContainsKey(hWnd)) {
|
|
||||||
WindowDetails childWindow = allWindows[hWnd];
|
|
||||||
// Force getting the clientRectangle, used for caching
|
|
||||||
Rectangle rect = childWindow.WindowRectangle;
|
|
||||||
sortedWindows.Add(childWindow);
|
|
||||||
// Remove so we can add the ones that were left over
|
|
||||||
allWindows.Remove(hWnd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Add missing children, those that didn't show up in the GetWindow enumeration
|
|
||||||
if (allWindows.Count > 0) {
|
|
||||||
Rectangle screenBounds = WindowCapture.GetScreenBounds();
|
|
||||||
// Copy not copied windows to the back, but only if visible
|
|
||||||
foreach(IntPtr hWnd in allWindows.Keys) {
|
|
||||||
WindowDetails notAddedChild = allWindows[hWnd];
|
|
||||||
Rectangle windowRect = notAddedChild.WindowRectangle;
|
|
||||||
if (windowRect.Width * windowRect.Height > 0 && screenBounds.Contains(windowRect)) {
|
|
||||||
sortedWindows.Add(notAddedChild);
|
|
||||||
} else {
|
|
||||||
LOG.DebugFormat("Skipping {0}", notAddedChild.ClassName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sortedWindows;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper method to "active" all windows that are not in the supplied list.
|
/// Helper method to "active" all windows that are not in the supplied list.
|
||||||
/// One should preferably call "GetVisibleWindows" for the oldWindows.
|
/// One should preferably call "GetVisibleWindows" for the oldWindows.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue