Skip to content

Commit a618c56

Browse files
committed
Refactored IPlayback and Message Windows..
- .. Moved wallpaper related logic to Core. - Removed detaching running wallpaper as screensaver. - PlaybackDeferrer impl
1 parent a4ee200 commit a618c56

File tree

21 files changed

+559
-502
lines changed

21 files changed

+559
-502
lines changed

src/Lively/Lively.Common/Extensions/WallpaperExtensions.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,25 @@ public static bool IsLocalWebWallpaper(this WallpaperType type) =>
3030
/// </summary>
3131
public static bool IsDirectoryProject(this WallpaperType type) =>
3232
IsApplicationWallpaper(type) || IsLocalWebWallpaper(type);
33+
34+
public static bool IsDeviceInputAllowed(this WallpaperType type)
35+
{
36+
return type switch
37+
{
38+
WallpaperType.app => true,
39+
WallpaperType.web => true,
40+
WallpaperType.webaudio => true,
41+
WallpaperType.url => true,
42+
WallpaperType.bizhawk => true,
43+
WallpaperType.unity => true,
44+
WallpaperType.godot => true,
45+
WallpaperType.video => false,
46+
WallpaperType.gif => false,
47+
WallpaperType.unityaudio => true,
48+
WallpaperType.videostream => false,
49+
WallpaperType.picture => false,
50+
_ => false,
51+
};
52+
}
3353
}
3454
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
using Lively.Common.Helpers.Pinvoke;
2+
using System;
3+
using System.Drawing;
4+
5+
namespace Lively.Common.Helpers
6+
{
7+
public static class InputUtil
8+
{
9+
static readonly IntPtr MK_LBUTTON = (IntPtr)0x0001;
10+
static readonly IntPtr MK_RBUTTON = (IntPtr)0x0002;
11+
static readonly IntPtr MK_MOVE = (IntPtr)0x0020;
12+
13+
public static bool IsMouseButtonsSwapped { get; } =
14+
NativeMethods.GetSystemMetrics((int)NativeMethods.SystemMetric.SM_SWAPBUTTON) != 0;
15+
16+
public static void MouseLeftButtonDown(IntPtr hwnd, int x, int y) =>
17+
ForwardMessageMouse(hwnd, x, y, (int)NativeMethods.WM.LBUTTONDOWN, MK_LBUTTON);
18+
19+
public static void MouseLeftButtonUp(IntPtr hwnd, int x, int y) =>
20+
ForwardMessageMouse(hwnd, x, y, (int)NativeMethods.WM.LBUTTONUP, MK_LBUTTON);
21+
22+
public static void MouseRightButtonDown(IntPtr hwnd, int x, int y) =>
23+
ForwardMessageMouse(hwnd, x, y, (int)NativeMethods.WM.RBUTTONDOWN, MK_RBUTTON);
24+
25+
public static void MouseRightButtonUp(IntPtr hwnd, int x, int y) =>
26+
ForwardMessageMouse(hwnd, x, y, (int)NativeMethods.WM.RBUTTONUP, MK_RBUTTON);
27+
28+
public static void MouseMove(IntPtr hwnd, int x, int y) =>
29+
ForwardMessageMouse(hwnd, x, y, (int)NativeMethods.WM.MOUSEMOVE, MK_MOVE);
30+
31+
/// <summary>
32+
/// Forward mouse input to the active/inactive window.
33+
/// </summary>
34+
/// <param name="hwnd">Target window handle</param>
35+
/// <param name="x">Cursor pos x</param>
36+
/// <param name="y">Cursor pos y</param>
37+
/// <param name="msg">mouse message</param>
38+
/// <param name="wParam">additional msg parameter</param>
39+
public static void ForwardMessageMouse(IntPtr hwnd, int x, int y, int msg, IntPtr wParam)
40+
{
41+
// The low-order word specifies the x-coordinate of the cursor, the high-order word specifies the y-coordinate of the cursor.
42+
// Ref: https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-mousemove
43+
uint lParam = Convert.ToUInt32(y);
44+
lParam <<= 16;
45+
lParam |= Convert.ToUInt32(x);
46+
NativeMethods.PostMessageW(hwnd, msg, wParam, (UIntPtr)lParam);
47+
}
48+
49+
/// <summary>
50+
/// Forward key input to the active/inactive window.
51+
/// </summary>
52+
/// <param name="hwnd">Target window handle</param>
53+
/// <param name="msg">key press msg</param>
54+
/// <param name="wParam">Virtual-Key code</param>
55+
/// <param name="scanCode">OEM code of the key</param>
56+
/// <param name="isPressed">Key is pressed</param>
57+
public static void ForwardMessageKeyboard(IntPtr hwnd, int msg, IntPtr wParam, int scanCode, bool isPressed)
58+
{
59+
//Ref:
60+
// https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-keydown
61+
// https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-keyup
62+
uint lParam = 1u; //press
63+
lParam |= (uint)scanCode << 16; //oem code
64+
lParam |= 1u << 24; //extended key
65+
lParam |= 0u << 29; //context code; Note: Alt key combos wont't work
66+
/* Same as:
67+
* lParam = isPressed ? (lParam |= 0u << 30) : (lParam |= 1u << 30); //prev key state
68+
* lParam = isPressed ? (lParam |= 0u << 31) : (lParam |= 1u << 31); //transition state
69+
*/
70+
lParam = isPressed ? lParam : (lParam |= 3u << 30);
71+
NativeMethods.PostMessageW(hwnd, msg, wParam, (UIntPtr)lParam);
72+
}
73+
74+
/// <summary>
75+
/// Converts global mouse position to per-display localized coordinates.
76+
/// </summary>
77+
public static Point ToMouseDisplayLocal(int x, int y, Rectangle displayBounds)
78+
{
79+
x += -1 * displayBounds.X;
80+
y += -1 * displayBounds.Y;
81+
return new Point(x, y);
82+
}
83+
84+
/// <summary>
85+
/// Converts global mouse position to span-local coordinates.
86+
/// </summary>
87+
public static Point ToMouseSpanLocal(int x, int y, Rectangle virtualScreenBounds)
88+
{
89+
x -= virtualScreenBounds.Location.X;
90+
y -= virtualScreenBounds.Location.Y;
91+
return new Point(x, y);
92+
}
93+
}
94+
}

src/Lively/Lively/Core/Suspend/VolumeMixer.cs renamed to src/Lively/Lively.Common/Helpers/VolumeMixerUtil.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
using System.Text;
66
using System.Threading.Tasks;
77

8-
namespace Lively.Core.Suspend
8+
namespace Lively.Common.Helpers
99
{
1010
//credit: https://stackoverflow.com/questions/14306048/controlling-volume-mixer
11-
public class VolumeMixer
11+
public class VolumeMixerUtil
1212
{
1313
public static float? GetApplicationVolume(int pid)
1414
{
@@ -59,7 +59,7 @@ public static void SetApplicationMute(int pid, bool mute)
5959
private static ISimpleAudioVolume GetVolumeObject(int pid)
6060
{
6161
// get the speakers (1st render + multimedia) device
62-
IMMDeviceEnumerator deviceEnumerator = (IMMDeviceEnumerator)(new MMDeviceEnumerator());
62+
IMMDeviceEnumerator deviceEnumerator = (IMMDeviceEnumerator)new MMDeviceEnumerator();
6363
IMMDevice speakers;
6464
deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out speakers);
6565

src/Lively/Lively.Common/Services/IScreensaverService.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@ public interface IScreensaverService
1919

2020
public enum ScreensaverApplyMode
2121
{
22-
/// <summary>
23-
/// Use the currently running wallpaper window itself.
24-
/// </summary>
25-
wallpaper,
2622
/// <summary>
2723
/// Create a new running wallpaper process.<bt>
2824
/// This is the only mode with support for running screensaver different from wallpaper.</bt>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace Lively.Models.Enums;
2+
3+
public enum PlaybackPolicy
4+
{
5+
automatic,
6+
alwaysPaused
7+
}

src/Lively/Lively.Models/Enums/PlaybackState.cs

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/Lively/Lively.UI.WinUI/Views/Pages/Settings/SettingsWallpaperView.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@
161161
</animations:Implicit.HideAnimations>
162162
</InfoBar>
163163

164-
<controls:SettingsExpander x:Uid="WebBrowser" IsExpanded="False">
164+
<controls:SettingsExpander x:Uid="WebBrowser" IsExpanded="True">
165165
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{Binding SelectedWebBrowserIndex, Mode=TwoWay}">
166166
<ComboBoxItem>CefSharp</ComboBoxItem>
167167
<ComboBoxItem>WebView2</ComboBoxItem>

src/Lively/Lively/App.xaml.cs

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22
using GrpcDotNetNamedPipes;
33
using Lively.Commandline;
44
using Lively.Common;
5-
using Lively.Common.Extensions;
65
using Lively.Common.Factories;
76
using Lively.Common.Helpers;
8-
using Lively.Common.Helpers.Archive;
9-
using Lively.Common.Helpers.Files;
7+
using Lively.Common.Helpers.Pinvoke;
108
using Lively.Common.Services;
119
using Lively.Core;
1210
using Lively.Core.Display;
@@ -18,20 +16,15 @@
1816
using Lively.Grpc.Common.Proto.Display;
1917
using Lively.Grpc.Common.Proto.Update;
2018
using Lively.Helpers;
21-
using Lively.Models;
2219
using Lively.Models.Enums;
2320
using Lively.Models.Services;
2421
using Lively.RPC;
2522
using Lively.Services;
2623
using Lively.ViewModels;
27-
using Lively.Views;
2824
using Lively.Views.WindowMsg;
2925
using Microsoft.Extensions.DependencyInjection;
30-
using Microsoft.Win32;
3126
using System;
32-
using System.Collections.Generic;
3327
using System.Diagnostics;
34-
using System.IO;
3528
using System.Linq;
3629
using System.Threading;
3730
using System.Threading.Tasks;
@@ -137,7 +130,31 @@ public App()
137130
QuitApp();
138131
return;
139132
}
140-
133+
134+
Services.GetRequiredService<WndProcMsgWindow>().WindowMessageReceived += (s, args) =>
135+
{
136+
if (args.Message == (uint)NativeMethods.WM.ENDSESSION)
137+
{
138+
QuitApp();
139+
}
140+
else if (args.Message == (uint)NativeMethods.WM.QUERYENDSESSION)
141+
{
142+
// ENDSESSION_CLOSEAPP
143+
if (args.LParam != IntPtr.Zero && args.LParam == (IntPtr)0x00000001)
144+
{
145+
ReleaseMutex();
146+
//The app is being queried if it can close for an update.
147+
_ = NativeMethods.RegisterApplicationRestart(
148+
null,
149+
(int)NativeMethods.RestartFlags.RESTART_NO_CRASH |
150+
(int)NativeMethods.RestartFlags.RESTART_NO_HANG |
151+
(int)NativeMethods.RestartFlags.RESTART_NO_REBOOT);
152+
153+
args.Result = (IntPtr)1;
154+
}
155+
}
156+
};
157+
141158
// System notification.
142159
Services.GetRequiredService<IDesktopCore>().WallpaperError += (s, e) =>
143160
{
@@ -176,8 +193,8 @@ public App()
176193
};
177194

178195
//Ref: https://github.com/Kinnara/ModernWpf/blob/master/ModernWpf/Helpers/ColorsHelper.cs
179-
SystemEvents.UserPreferenceChanged += (s, e) => {
180-
if (e.Category == UserPreferenceCategory.General)
196+
Microsoft.Win32.SystemEvents.UserPreferenceChanged += (s, e) => {
197+
if (e.Category == Microsoft.Win32.UserPreferenceCategory.General)
181198
{
182199
if (userSettings.Settings.ApplicationTheme == Models.Enums.AppTheme.Auto)
183200
{

src/Lively/Lively/Commandline/CommandHandler.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ private async Task RunAppOptions(AppOptions opts)
106106

107107
if (opts.Play != null)
108108
{
109-
playbackMonitor.WallpaperPlayback = (bool)opts.Play ? PlaybackState.play : PlaybackState.paused;
109+
playbackMonitor.WallpaperPlaybackPolicy = (bool)opts.Play ? PlaybackPolicy.automatic : PlaybackPolicy.alwaysPaused;
110110
}
111111

112112
if (opts.Startup != null)
@@ -343,11 +343,19 @@ private void SeekWallpaper(float seek, PlaybackPosType type, DisplayMonitor scre
343343
switch (userSettings.Settings.WallpaperArrangement)
344344
{
345345
case WallpaperArrangement.per:
346-
desktopCore.SeekWallpaper(screen, seek, type);
346+
foreach (var wallpaper in desktopCore.Wallpapers)
347+
{
348+
if (wallpaper.Screen.Equals(screen))
349+
wallpaper.SetPlaybackPos(seek, type);
350+
}
347351
break;
348352
case WallpaperArrangement.span:
349353
case WallpaperArrangement.duplicate:
350-
desktopCore.SeekWallpaper(wp, seek, type);
354+
foreach (var wallpaper in desktopCore.Wallpapers)
355+
{
356+
if (wallpaper.Model == wp)
357+
wallpaper.SetPlaybackPos(seek, type);
358+
}
351359
break;
352360
}
353361
}

src/Lively/Lively/Core/Display/DisplayManager.cs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using CommunityToolkit.Mvvm.ComponentModel;
77
using Lively.Common.Helpers.Pinvoke;
88
using Lively.Models;
9+
using Lively.Views.WindowMsg;
910
using System;
1011
using System.Collections.Generic;
1112
using System.Collections.ObjectModel;
@@ -48,25 +49,29 @@ public Rectangle VirtualScreenBounds
4849
public DisplayMonitor PrimaryDisplayMonitor => DisplayMonitors
4950
.FirstOrDefault(x => x.IsPrimary);
5051

51-
public DisplayManager()
52-
{
53-
RefreshDisplayMonitorList();
54-
}
52+
private readonly WndProcMsgWindow wndProc;
5553

56-
public uint OnHwndCreated(IntPtr hWnd, out bool register)
54+
public DisplayManager(WndProcMsgWindow wndProc)
5755
{
58-
register = false;
59-
return 0;
56+
this.wndProc = wndProc;
57+
this.wndProc.WindowMessageReceived += WndProc_WindowMessageReceived;
58+
59+
RefreshDisplayMonitorList();
6060
}
6161

62-
public IntPtr OnWndProc(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam)
62+
private void WndProc_WindowMessageReceived(object sender, WindowMessageEventArgs args)
6363
{
64-
if (msg == (uint)NativeMethods.WM.DISPLAYCHANGE)
64+
if (args.Message == (uint)NativeMethods.WM.DISPLAYCHANGE)
6565
//|| (msg == (uint)NativeMethods.WM.SETTINGCHANGE && wParam == ((IntPtr)NativeMethods.SPI.SPI_SETWORKAREA)))
6666
{
6767
RefreshDisplayMonitorList();
6868
}
69-
return IntPtr.Zero;
69+
}
70+
71+
public uint OnHwndCreated(IntPtr hWnd, out bool register)
72+
{
73+
register = false;
74+
return 0;
7075
}
7176

7277
public DisplayMonitor GetDisplayMonitorFromHWnd(IntPtr hWnd)

0 commit comments

Comments
 (0)