diff --git a/Core/FormBrowser.cs b/Core/FormBrowser.cs index 6bd8f79a..c72253ee 100644 --- a/Core/FormBrowser.cs +++ b/Core/FormBrowser.cs @@ -26,6 +26,12 @@ private static UserConfig Config{ public string UpdateInstallerPath { get; private set; } + public FormNotification BrowserNotificationForm{ + get{ + return notification; + } + } + private readonly ChromiumWebBrowser browser; private readonly PluginManager plugins; private readonly UpdateHandler updates; @@ -38,6 +44,7 @@ private static UserConfig Config{ private FormWindowState prevState; + private TweetScreenshotManager notificationScreenshotManager; private SoundPlayer notificationSound; public FormBrowser(PluginManager pluginManager, UpdaterSettings updaterSettings){ @@ -73,6 +80,10 @@ public FormBrowser(PluginManager pluginManager, UpdaterSettings updaterSettings) Disposed += (sender, args) => { browser.Dispose(); + if (notificationScreenshotManager != null){ + notificationScreenshotManager.Dispose(); + } + if (notificationSound != null){ notificationSound.Dispose(); } @@ -319,33 +330,11 @@ public void PlayNotificationSound(){ } public void OnTweetScreenshotReady(string html, int width, int height){ - FormNotification dummyWindow = CreateNotificationForm(NotificationFlags.DisableScripts | NotificationFlags.DisableContextMenu | NotificationFlags.TopMost); + if (notificationScreenshotManager == null){ + notificationScreenshotManager = new TweetScreenshotManager(this); + } - dummyWindow.ShowNotificationForScreenshot(new TweetNotification(html, string.Empty, 0), width, height, () => { - Point? prevNotificationLocation = null; - bool prevFreezeTimer = false; - - if (notification.IsNotificationVisible){ - prevNotificationLocation = notification.Location; - prevFreezeTimer = notification.FreezeTimer; - - notification.Location = ControlExtensions.InvisibleLocation; - notification.FreezeTimer = true; - } - - dummyWindow.TakeScreenshot(); - dummyWindow.Hide(); - dummyWindow.Close(); - // dummyWindow.Dispose(); // TODO something freezes the program sometimes - - if (prevNotificationLocation.HasValue){ - notification.Location = prevNotificationLocation.Value; - notification.FreezeTimer = prevFreezeTimer; - } - }); - - dummyWindow.CanMoveWindow = () => false; - dummyWindow.Show(); + notificationScreenshotManager.Trigger(html, width, height); } public void DisplayTooltip(string text){ diff --git a/Core/FormNotification.cs b/Core/FormNotification.cs index eab237a1..b7a5240a 100644 --- a/Core/FormNotification.cs +++ b/Core/FormNotification.cs @@ -28,7 +28,7 @@ public bool IsNotificationVisible{ } } - private readonly Form owner; + private readonly Control owner; private readonly PluginManager plugins; private readonly ChromiumWebBrowser browser; private readonly NotificationFlags flags; @@ -101,11 +101,6 @@ public FormNotification(FormBrowser owner, PluginManager pluginManager, Notifica owner.FormClosed += (sender, args) => Close(); - if (!flags.HasFlag(NotificationFlags.DisableScripts)){ - notificationJS = ScriptLoader.LoadResource(NotificationScriptFile); - pluginJS = ScriptLoader.LoadResource(PluginManager.PluginNotificationScriptFile); - } - browser = new ChromiumWebBrowser("about:blank"){ MenuHandler = new ContextMenuNotification(this, !flags.HasFlag(NotificationFlags.DisableContextMenu)), LifeSpanHandler = new LifeSpanHandler() @@ -117,8 +112,16 @@ public FormNotification(FormBrowser owner, PluginManager pluginManager, Notifica browser.IsBrowserInitializedChanged += Browser_IsBrowserInitializedChanged; browser.FrameLoadEnd += Browser_FrameLoadEnd; - browser.RegisterJsObject("$TD", new TweetDeckBridge(owner, this)); - browser.RegisterAsyncJsObject("$TDP", plugins.Bridge); + + if (!flags.HasFlag(NotificationFlags.DisableScripts)){ + notificationJS = ScriptLoader.LoadResource(NotificationScriptFile); + browser.RegisterJsObject("$TD", new TweetDeckBridge(owner, this)); + + if (plugins != null){ + pluginJS = ScriptLoader.LoadResource(PluginManager.PluginNotificationScriptFile); + browser.RegisterAsyncJsObject("$TDP", plugins.Bridge); + } + } panelBrowser.Controls.Add(browser); @@ -210,7 +213,7 @@ private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){ else if (notificationJS != null && browser.Address != "about:blank" && !flags.HasFlag(NotificationFlags.DisableScripts)){ ScriptLoader.ExecuteScript(e.Frame, notificationJS, NotificationScriptIdentifier); - if (plugins.HasAnyPlugin(PluginEnvironment.Notification)){ + if (plugins != null && plugins.HasAnyPlugin(PluginEnvironment.Notification)){ ScriptLoader.ExecuteScript(e.Frame, pluginJS, PluginScriptIdentifier); ScriptLoader.ExecuteFile(e.Frame, PluginManager.PluginGlobalScriptFile); plugins.ExecutePlugins(e.Frame, PluginEnvironment.Notification, false); @@ -256,29 +259,32 @@ public void ShowNotificationForSettings(bool reset){ } } - public void ShowNotificationForScreenshot(TweetNotification tweet, int width, int height, Action callback){ + public void PrepareNotificationForScreenshot(Action callback){ browser.RegisterAsyncJsObject("$TD_NotificationScreenshot", new CallbackBridge(this, callback)); browser.FrameLoadEnd += (sender, args) => { - if (args.Frame.IsMain){ + if (args.Frame.IsMain && browser.Address != "about:blank"){ ScriptLoader.ExecuteScript(args.Frame, "window.setTimeout(() => $TD_NotificationScreenshot.trigger(), 25)", "gen:screenshot"); } }; + } + public void LoadNotificationForScreenshot(TweetNotification tweet, int width, int height){ browser.LoadHtml(tweet.GenerateHtml(enableCustomCSS: false), "http://tweetdeck.twitter.com/?"+DateTime.Now.Ticks); Location = ControlExtensions.InvisibleLocation; ClientSize = new Size(width, height); progressBarTimer.Visible = false; panelBrowser.Height = height; - - // TODO start a timer on 10 seconds to close the window if anything fails or takes too long } - public void TakeScreenshot(){ + public void TakeScreenshotAndHide(){ MoveToVisibleLocation(); Activate(); SendKeys.SendWait("%{PRTSC}"); + + Location = ControlExtensions.InvisibleLocation; + browser.LoadHtml("", "about:blank"); } public void HideNotification(bool loadBlank){ diff --git a/Core/Utils/Notification/TweetScreenshotManager.cs b/Core/Utils/Notification/TweetScreenshotManager.cs new file mode 100644 index 00000000..fc8ea110 --- /dev/null +++ b/Core/Utils/Notification/TweetScreenshotManager.cs @@ -0,0 +1,54 @@ +using System; +using System.Drawing; +using TweetDck.Core.Controls; +using TweetDck.Core.Handling; + +namespace TweetDck.Core.Utils.Notification{ + class TweetScreenshotManager : IDisposable{ + private readonly FormBrowser browser; + private readonly FormNotification screenshot; + + public TweetScreenshotManager(FormBrowser browser){ + this.browser = browser; + + this.screenshot = new FormNotification(browser, null, NotificationFlags.DisableScripts | NotificationFlags.DisableContextMenu | NotificationFlags.TopMost){ + CanMoveWindow = () => false + }; + + this.screenshot.PrepareNotificationForScreenshot(Callback); + } + + public void Trigger(string html, int width, int height){ + screenshot.LoadNotificationForScreenshot(new TweetNotification(html, string.Empty, 0), width, height); + screenshot.Show(); + + // TODO start a timer on 10 seconds to close the window if anything fails or takes too long + } + + private void Callback(){ + FormNotification notification = browser.BrowserNotificationForm; + + Point? prevNotificationLocation = null; + bool prevFreezeTimer = false; + + if (notification.IsNotificationVisible){ + prevNotificationLocation = notification.Location; + prevFreezeTimer = notification.FreezeTimer; + + notification.Location = ControlExtensions.InvisibleLocation; + notification.FreezeTimer = true; + } + + screenshot.TakeScreenshotAndHide(); + + if (prevNotificationLocation.HasValue){ + notification.Location = prevNotificationLocation.Value; + notification.FreezeTimer = prevFreezeTimer; + } + } + + public void Dispose(){ + screenshot.Dispose(); + } + } +} diff --git a/TweetDck.csproj b/TweetDck.csproj index 3622fc47..896d366e 100644 --- a/TweetDck.csproj +++ b/TweetDck.csproj @@ -178,6 +178,7 @@ <Compile Include="Core\Utils\CommandLineArgs.cs" /> <Compile Include="Core\Utils\CommandLineArgsParser.cs" /> <Compile Include="Core\Utils\Notification\NotificationFlags.cs" /> + <Compile Include="Core\Utils\Notification\TweetScreenshotManager.cs" /> <Compile Include="Core\Utils\WindowState.cs" /> <Compile Include="Core\Utils\WindowsUtils.cs" /> <Compile Include="Core\Handling\TweetDeckBridge.cs" />