mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-05-30 14:34:08 +02:00
Fix various focus issues with video player and fix double-clicking control panel
This commit is contained in:
parent
92f1e9f7ec
commit
14a9edeb73
@ -405,7 +405,6 @@ protected override void WndProc(ref Message m){
|
|||||||
if (isBrowserReady && m.Msg == NativeMethods.WM_PARENTNOTIFY && (m.WParam.ToInt32() & 0xFFFF) == NativeMethods.WM_XBUTTONDOWN){
|
if (isBrowserReady && m.Msg == NativeMethods.WM_PARENTNOTIFY && (m.WParam.ToInt32() & 0xFFFF) == NativeMethods.WM_XBUTTONDOWN){
|
||||||
if (videoPlayer != null && videoPlayer.Running){
|
if (videoPlayer != null && videoPlayer.Running){
|
||||||
videoPlayer.Close();
|
videoPlayer.Close();
|
||||||
HideVideoOverlay();
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
browser.ExecuteScriptAsync("TDGF_onMouseClickExtra", (m.WParam.ToInt32() >> 16) & 0xFFFF);
|
browser.ExecuteScriptAsync("TDGF_onMouseClickExtra", (m.WParam.ToInt32() >> 16) & 0xFFFF);
|
||||||
@ -527,7 +526,11 @@ public void PlayVideo(string url){
|
|||||||
|
|
||||||
if (videoPlayer == null){
|
if (videoPlayer == null){
|
||||||
videoPlayer = new VideoPlayer(this);
|
videoPlayer = new VideoPlayer(this);
|
||||||
videoPlayer.ProcessExitedGracelessly += (sender, args) => HideVideoOverlay();
|
|
||||||
|
videoPlayer.ProcessExited += (sender, args) => {
|
||||||
|
browser.GetBrowser().GetHost().SendFocusEvent(true);
|
||||||
|
HideVideoOverlay();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
videoPlayer.Launch(url);
|
videoPlayer.Launch(url);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using TweetDuck.Core.Controls;
|
||||||
using TweetDuck.Core.Utils;
|
using TweetDuck.Core.Utils;
|
||||||
|
|
||||||
namespace TweetDuck.Core.Other.Management{
|
namespace TweetDuck.Core.Other.Management{
|
||||||
@ -19,7 +20,7 @@ public bool Running{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler ProcessExitedGracelessly;
|
public event EventHandler ProcessExited;
|
||||||
|
|
||||||
private readonly Form owner;
|
private readonly Form owner;
|
||||||
private Process currentProcess;
|
private Process currentProcess;
|
||||||
@ -27,6 +28,7 @@ public bool Running{
|
|||||||
|
|
||||||
public VideoPlayer(Form owner){
|
public VideoPlayer(Form owner){
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
|
this.owner.FormClosing += owner_FormClosing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Launch(string url){
|
public void Launch(string url){
|
||||||
@ -66,6 +68,14 @@ public void Close(){
|
|||||||
|
|
||||||
currentProcess.Dispose();
|
currentProcess.Dispose();
|
||||||
currentProcess = null;
|
currentProcess = null;
|
||||||
|
|
||||||
|
owner.InvokeAsyncSafe(TriggerProcessExitEventUnsafe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void owner_FormClosing(object sender, FormClosingEventArgs e){
|
||||||
|
if (currentProcess != null){
|
||||||
|
currentProcess.Exited -= process_Exited;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,12 +96,14 @@ private void process_Exited(object sender, EventArgs e){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentProcess.ExitCode != 0){
|
|
||||||
ProcessExitedGracelessly?.Invoke(this, new EventArgs());
|
|
||||||
}
|
|
||||||
|
|
||||||
currentProcess.Dispose();
|
currentProcess.Dispose();
|
||||||
currentProcess = null;
|
currentProcess = null;
|
||||||
|
|
||||||
|
owner.InvokeAsyncSafe(TriggerProcessExitEventUnsafe);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TriggerProcessExitEventUnsafe(){
|
||||||
|
ProcessExited?.Invoke(this, new EventArgs());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,13 @@
|
|||||||
|
|
||||||
namespace TweetDuck.Video{
|
namespace TweetDuck.Video{
|
||||||
partial class FormPlayer : Form{
|
partial class FormPlayer : Form{
|
||||||
|
protected override bool ShowWithoutActivation => true;
|
||||||
|
|
||||||
private readonly IntPtr ownerHandle;
|
private readonly IntPtr ownerHandle;
|
||||||
private readonly string videoUrl;
|
private readonly string videoUrl;
|
||||||
|
|
||||||
private readonly ControlWMP player;
|
private readonly ControlWMP player;
|
||||||
|
private bool wasCursorInside;
|
||||||
private bool isPaused;
|
private bool isPaused;
|
||||||
private bool isDragging;
|
private bool isDragging;
|
||||||
|
|
||||||
@ -67,10 +70,12 @@ private void timerSync_Tick(object sender, EventArgs e){
|
|||||||
int height = rect.Bottom-rect.Top+1;
|
int height = rect.Bottom-rect.Top+1;
|
||||||
IWMPMedia media = Player.currentMedia;
|
IWMPMedia media = Player.currentMedia;
|
||||||
|
|
||||||
|
bool isCursorInside = ClientRectangle.Contains(PointToClient(Cursor.Position));
|
||||||
|
|
||||||
ClientSize = new Size(Math.Min(media.imageSourceWidth, width*3/4), Math.Min(media.imageSourceHeight, height*3/4));
|
ClientSize = new Size(Math.Min(media.imageSourceWidth, width*3/4), Math.Min(media.imageSourceHeight, height*3/4));
|
||||||
Location = new Point(rect.Left+(width-ClientSize.Width)/2, rect.Top+(height-ClientSize.Height+SystemInformation.CaptionHeight)/2);
|
Location = new Point(rect.Left+(width-ClientSize.Width)/2, rect.Top+(height-ClientSize.Height+SystemInformation.CaptionHeight)/2);
|
||||||
|
|
||||||
tablePanel.Visible = ClientRectangle.Contains(PointToClient(Cursor.Position)) || isDragging;
|
tablePanel.Visible = isCursorInside || isDragging;
|
||||||
|
|
||||||
if (tablePanel.Visible){
|
if (tablePanel.Visible){
|
||||||
labelTime.Text = $"{Player.controls.currentPositionString} / {Player.currentMedia.durationString}";
|
labelTime.Text = $"{Player.controls.currentPositionString} / {Player.currentMedia.durationString}";
|
||||||
@ -93,6 +98,17 @@ private void timerSync_Tick(object sender, EventArgs e){
|
|||||||
Player.controls.currentPosition = 0;
|
Player.controls.currentPosition = 0;
|
||||||
Player.controls.play();
|
Player.controls.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isCursorInside && !wasCursorInside){
|
||||||
|
wasCursorInside = true;
|
||||||
|
}
|
||||||
|
else if (!isCursorInside && wasCursorInside){
|
||||||
|
wasCursorInside = false;
|
||||||
|
|
||||||
|
if (!Player.fullScreen){
|
||||||
|
NativeMethods.SetForegroundWindow(ownerHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
Environment.Exit(Program.CODE_OWNER_GONE);
|
Environment.Exit(Program.CODE_OWNER_GONE);
|
||||||
@ -143,23 +159,33 @@ private void TogglePause(){
|
|||||||
internal class MessageFilter : IMessageFilter{
|
internal class MessageFilter : IMessageFilter{
|
||||||
private readonly FormPlayer form;
|
private readonly FormPlayer form;
|
||||||
|
|
||||||
|
private bool IsCursorOverVideo{
|
||||||
|
get{
|
||||||
|
Point cursor = form.PointToClient(Cursor.Position);
|
||||||
|
return cursor.Y < form.tablePanel.Location.Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public MessageFilter(FormPlayer form){
|
public MessageFilter(FormPlayer form){
|
||||||
this.form = form;
|
this.form = form;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IMessageFilter.PreFilterMessage(ref Message m){
|
bool IMessageFilter.PreFilterMessage(ref Message m){
|
||||||
if (m.Msg == 0x0201){ // WM_LBUTTONDOWN
|
if (m.Msg == 0x0201){ // WM_LBUTTONDOWN
|
||||||
Point cursor = form.PointToClient(Cursor.Position);
|
if (IsCursorOverVideo){
|
||||||
|
|
||||||
if (cursor.Y < form.tablePanel.Location.Y){
|
|
||||||
form.TogglePause();
|
form.TogglePause();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m.Msg == 0x0203 || (m.Msg == 0x0100 && m.WParam.ToInt32() == 0x20)){ // WM_LBUTTONDBLCLK, WM_KEYDOWN, VK_SPACE
|
else if (m.Msg == 0x0203 || (m.Msg == 0x0100 && m.WParam.ToInt32() == 0x20)){ // WM_LBUTTONDBLCLK, WM_KEYDOWN, VK_SPACE
|
||||||
form.TogglePause();
|
if (IsCursorOverVideo){
|
||||||
|
form.TogglePause();
|
||||||
|
form.Player.fullScreen = !form.Player.fullScreen;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (m.Msg == 0x020B && ((m.WParam.ToInt32() >> 16) & 0xFFFF) == 1){ // WM_XBUTTONDOWN
|
else if (m.Msg == 0x020B && ((m.WParam.ToInt32() >> 16) & 0xFFFF) == 1){ // WM_XBUTTONDOWN
|
||||||
|
NativeMethods.SetForegroundWindow(form.ownerHandle);
|
||||||
Environment.Exit(Program.CODE_USER_REQUESTED);
|
Environment.Exit(Program.CODE_USER_REQUESTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,9 @@ static class NativeMethods{
|
|||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern bool SetForegroundWindow(IntPtr hWnd);
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct RECT{
|
public struct RECT{
|
||||||
public int Left;
|
public int Left;
|
||||||
|
Loading…
Reference in New Issue
Block a user