You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

WindowFlashingManager.java 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * Copyright (c) 2006-2017 DMDirc Developers
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
  5. * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
  6. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
  7. * permit persons to whom the Software is furnished to do so, subject to the following conditions:
  8. *
  9. * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
  10. * Software.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  13. * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
  14. * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  15. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  16. */
  17. package com.dmdirc.addons.windowflashing;
  18. import com.dmdirc.addons.ui_swing.MainFrame;
  19. import com.dmdirc.addons.ui_swing.events.ClientFocusGainedEvent;
  20. import com.dmdirc.config.ConfigBinder;
  21. import com.dmdirc.config.ConfigBinding;
  22. import com.dmdirc.config.GlobalConfig;
  23. import com.dmdirc.config.prefs.PluginPreferencesCategory;
  24. import com.dmdirc.config.prefs.PreferencesCategory;
  25. import com.dmdirc.config.prefs.PreferencesDialogModel;
  26. import com.dmdirc.config.prefs.PreferencesSetting;
  27. import com.dmdirc.config.prefs.PreferencesType;
  28. import com.dmdirc.events.ClientPrefsOpenedEvent;
  29. import com.dmdirc.events.eventbus.EventBus;
  30. import com.dmdirc.interfaces.config.AggregateConfigProvider;
  31. import com.dmdirc.plugins.PluginDomain;
  32. import com.dmdirc.plugins.PluginInfo;
  33. import com.sun.jna.Native;
  34. import com.sun.jna.NativeLibrary;
  35. import com.sun.jna.Pointer;
  36. import com.sun.jna.platform.win32.User32;
  37. import com.sun.jna.platform.win32.WinDef;
  38. import com.sun.jna.platform.win32.WinUser;
  39. import javax.inject.Inject;
  40. import javax.inject.Singleton;
  41. import net.engio.mbassy.listener.Handler;
  42. @Singleton
  43. public class WindowFlashingManager {
  44. private final PluginInfo pluginInfo;
  45. /** Swing main frame. */
  46. private final MainFrame mainFrame;
  47. /** Event bus. */
  48. private final EventBus eventBus;
  49. /** Config binder. */
  50. private final ConfigBinder binder;
  51. /** Cached blink rate setting. */
  52. @ConfigBinding(domain = "plugin-windowflashing", key = "blinkrate",
  53. fallbacks = {"plugin-windowflashing", "blinkratefallback"})
  54. private int blinkrate;
  55. /** Cached count setting. */
  56. @ConfigBinding(domain = "plugin-windowflashing", key = "flashcount",
  57. fallbacks = {"plugin-windowflashing", "flashcountfallback"})
  58. private int flashcount;
  59. /** Cached flash taskbar setting. */
  60. @ConfigBinding(domain = "plugin-windowflashing", key = "flashtaskbar")
  61. private boolean flashtaskbar;
  62. /** Cached flash caption setting. */
  63. @ConfigBinding(domain = "plugin-windowflashing", key = "flashcaption")
  64. private boolean flashcaption;
  65. /** Library instance. */
  66. private User32 user32;
  67. @Inject
  68. public WindowFlashingManager(
  69. @GlobalConfig final AggregateConfigProvider config,
  70. @PluginDomain(WindowFlashing.class) final PluginInfo pluginInfo,
  71. final MainFrame mainFrame,
  72. final EventBus eventBus) {
  73. this.pluginInfo = pluginInfo;
  74. this.mainFrame = mainFrame;
  75. this.eventBus = eventBus;
  76. binder = config.getBinder();
  77. }
  78. public void onLoad() {
  79. user32 = (User32) Native.loadLibrary("user32", User32.class);
  80. binder.bind(this, WindowFlashing.class);
  81. eventBus.subscribe(this);
  82. }
  83. public void onUnload() {
  84. eventBus.unsubscribe(this);
  85. binder.unbind(this);
  86. user32 = null;
  87. NativeLibrary.getInstance("user32").dispose();
  88. }
  89. /**
  90. * Flashes an inactive window under windows.
  91. */
  92. public void flashWindow() {
  93. if (!mainFrame.isFocused()) {
  94. user32.FlashWindowEx(setupFlashObject());
  95. }
  96. }
  97. /**
  98. * Creates a new flash info object that starts flashing with the configured settings.
  99. */
  100. private WinUser.FLASHWINFO setupFlashObject() {
  101. final WinUser.FLASHWINFO flashInfo = new WinUser.FLASHWINFO();
  102. flashInfo.dwFlags = getFlags();
  103. flashInfo.dwTimeout = blinkrate;
  104. flashInfo.uCount = flashcount;
  105. flashInfo.hWnd = getHWND();
  106. flashInfo.cbSize = flashInfo.size();
  107. return flashInfo;
  108. }
  109. /**
  110. * Creates a new flash object that stops the flashing.
  111. */
  112. private WinUser.FLASHWINFO stopFlashObject() {
  113. final WinUser.FLASHWINFO flashInfo = new WinUser.FLASHWINFO();
  114. flashInfo.dwFlags = WinUser.FLASHW_STOP;
  115. flashInfo.dwTimeout = 0;
  116. flashInfo.uCount = 0;
  117. flashInfo.hWnd = getHWND();
  118. flashInfo.cbSize = flashInfo.size();
  119. return flashInfo;
  120. }
  121. /**
  122. * Returns the native handle object for the main frame.
  123. *
  124. * @return
  125. */
  126. private WinDef.HWND getHWND() {
  127. final WinDef.HWND hwnd = new WinDef.HWND();
  128. final Pointer pointer = Native.getWindowPointer(mainFrame);
  129. hwnd.setPointer(pointer);
  130. return hwnd;
  131. }
  132. /**
  133. * Calculates the flags for the flash object based on config settings.
  134. *
  135. * @return Flash info flags
  136. */
  137. private int getFlags() {
  138. int returnValue = 0;
  139. if (flashtaskbar) {
  140. returnValue |= WinUser.FLASHW_TRAY;
  141. }
  142. if (flashcaption) {
  143. returnValue |= WinUser.FLASHW_CAPTION;
  144. }
  145. if (flashcount >= 0) {
  146. returnValue |= WinUser.FLASHW_TIMER;
  147. } else {
  148. returnValue |= WinUser.FLASHW_TIMERNOFG;
  149. }
  150. return returnValue;
  151. }
  152. @Handler
  153. public void handleFocusGained(final ClientFocusGainedEvent event) {
  154. if (mainFrame != null) {
  155. user32.FlashWindowEx(stopFlashObject());
  156. }
  157. }
  158. @Handler
  159. public void showConfig(final ClientPrefsOpenedEvent event) {
  160. final PreferencesDialogModel manager = event.getModel();
  161. final PreferencesCategory category = new PluginPreferencesCategory(
  162. pluginInfo, "Window Flashing",
  163. "General configuration for window flashing plugin.");
  164. category.addSetting(new PreferencesSetting(
  165. PreferencesType.OPTIONALINTEGER, pluginInfo.getDomain(), "blinkrate",
  166. "Blink rate", "Specifies the rate at which the taskbar and or "
  167. + "caption will blink, if unspecified this will be your cursor "
  168. + "blink rate.",
  169. manager.getConfigManager(), manager.getIdentity()));
  170. category.addSetting(new PreferencesSetting(
  171. PreferencesType.OPTIONALINTEGER, pluginInfo.getDomain(), "flashcount",
  172. "Flash count", "Specifies the number of times to blink, if "
  173. + "unspecified this will blink indefinitely",
  174. manager.getConfigManager(), manager.getIdentity()));
  175. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  176. pluginInfo.getDomain(), "flashtaskbar", "Flash taskbar",
  177. "Should the taskbar entry flash?",
  178. manager.getConfigManager(), manager.getIdentity()));
  179. category.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
  180. pluginInfo.getDomain(), "flashcaption", "Flash caption",
  181. "Should the window caption flash?",
  182. manager.getConfigManager(), manager.getIdentity()));
  183. manager.getCategory("Plugins").addSubCategory(category);
  184. }
  185. }