upstream
This commit is contained in:
@@ -103,6 +103,10 @@ public class Notifier
|
||||
|
||||
private static final String appName = RuneLiteProperties.getTitle();
|
||||
|
||||
private static final File NOTIFICATION_FILE = new File(RuneLite.RUNELITE_DIR, "notification.wav");
|
||||
private static final long CLIP_MTIME_UNLOADED = -2;
|
||||
private static final long CLIP_MTIME_BUILTIN = -1;
|
||||
|
||||
private final Client client;
|
||||
private final RuneLiteConfig runeLiteConfig;
|
||||
private final ClientUI clientUI;
|
||||
@@ -113,6 +117,8 @@ public class Notifier
|
||||
private final boolean terminalNotifierAvailable;
|
||||
private Instant flashStart;
|
||||
private long mouseLastPressedMillis;
|
||||
private long lastClipMTime = CLIP_MTIME_UNLOADED;
|
||||
private Clip clip = null;
|
||||
|
||||
@Inject
|
||||
private Notifier(
|
||||
@@ -405,47 +411,73 @@ public class Notifier
|
||||
}
|
||||
}
|
||||
|
||||
private void playCustomSound()
|
||||
private synchronized void playCustomSound()
|
||||
{
|
||||
Clip clip = null;
|
||||
|
||||
// Try to load the user sound from ~/.runelite/notification.wav
|
||||
File file = new File(RuneLite.RUNELITE_DIR, "notification.wav");
|
||||
if (file.exists())
|
||||
long currentMTime = NOTIFICATION_FILE.exists() ? NOTIFICATION_FILE.lastModified() : CLIP_MTIME_BUILTIN;
|
||||
if (clip == null || currentMTime != lastClipMTime || !clip.isOpen())
|
||||
{
|
||||
if (clip != null)
|
||||
{
|
||||
clip.close();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
InputStream fileStream = new BufferedInputStream(new FileInputStream(file));
|
||||
try (AudioInputStream sound = AudioSystem.getAudioInputStream(fileStream))
|
||||
{
|
||||
clip = AudioSystem.getClip();
|
||||
clip.open(sound);
|
||||
}
|
||||
}
|
||||
catch (UnsupportedAudioFileException | IOException | LineUnavailableException e)
|
||||
{
|
||||
clip = null;
|
||||
log.warn("Unable to play notification sound", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (clip == null)
|
||||
{
|
||||
// Otherwise load from the classpath
|
||||
InputStream fileStream = new BufferedInputStream(Notifier.class.getResourceAsStream("notification.wav"));
|
||||
try (AudioInputStream sound = AudioSystem.getAudioInputStream(fileStream))
|
||||
{
|
||||
clip = AudioSystem.getClip();
|
||||
clip.open(sound);
|
||||
}
|
||||
catch (UnsupportedAudioFileException | IOException | LineUnavailableException e)
|
||||
catch (LineUnavailableException e)
|
||||
{
|
||||
log.warn("Unable to play builtin notification sound", e);
|
||||
lastClipMTime = CLIP_MTIME_UNLOADED;
|
||||
log.warn("Unable to play notification", e);
|
||||
Toolkit.getDefaultToolkit().beep();
|
||||
return;
|
||||
}
|
||||
|
||||
lastClipMTime = currentMTime;
|
||||
|
||||
if (!tryLoadNotification())
|
||||
{
|
||||
Toolkit.getDefaultToolkit().beep();
|
||||
return;
|
||||
}
|
||||
}
|
||||
clip.start();
|
||||
|
||||
// Using loop instead of start + setFramePosition prevents a the clip
|
||||
// from not being played sometimes, presumably a race condition in the
|
||||
// underlying line driver
|
||||
clip.loop(1);
|
||||
}
|
||||
|
||||
private boolean tryLoadNotification()
|
||||
{
|
||||
if (NOTIFICATION_FILE.exists())
|
||||
{
|
||||
try
|
||||
{
|
||||
InputStream fileStream = new BufferedInputStream(new FileInputStream(NOTIFICATION_FILE));
|
||||
try (AudioInputStream sound = AudioSystem.getAudioInputStream(fileStream))
|
||||
{
|
||||
clip.open(sound);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (UnsupportedAudioFileException | IOException | LineUnavailableException e)
|
||||
{
|
||||
log.warn("Unable to load notification sound", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise load from the classpath
|
||||
InputStream fileStream = new BufferedInputStream(Notifier.class.getResourceAsStream("notification.wav"));
|
||||
try (AudioInputStream sound = AudioSystem.getAudioInputStream(fileStream))
|
||||
{
|
||||
clip.open(sound);
|
||||
return true;
|
||||
}
|
||||
catch (UnsupportedAudioFileException | IOException | LineUnavailableException e)
|
||||
{
|
||||
log.warn("Unable to load builtin notification sound", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,7 +593,11 @@ public class ChatMessageManager
|
||||
|
||||
// Update the message with RuneLite additions
|
||||
line.setRuneLiteFormatMessage(message.getRuneLiteFormattedMessage());
|
||||
line.setTimestamp(message.getTimestamp());
|
||||
|
||||
if (message.getTimestamp() != 0)
|
||||
{
|
||||
line.setTimestamp(message.getTimestamp());
|
||||
}
|
||||
|
||||
update(line);
|
||||
}
|
||||
|
||||
@@ -225,29 +225,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
||||
|
||||
for (Overlay overlay : overlays)
|
||||
{
|
||||
OverlayPosition overlayPosition = overlay.getPosition();
|
||||
|
||||
if (overlay.getPreferredPosition() != null)
|
||||
{
|
||||
overlayPosition = overlay.getPreferredPosition();
|
||||
}
|
||||
|
||||
if (!isResizeable)
|
||||
{
|
||||
// On fixed mode, ABOVE_CHATBOX_RIGHT is in the same location as
|
||||
// BOTTOM_RIGHT and CANVAS_TOP_RIGHT is same as TOP_RIGHT.
|
||||
// Just use BOTTOM_RIGHT and TOP_RIGHT to prevent overlays from
|
||||
// drawing over each other.
|
||||
switch (overlayPosition)
|
||||
{
|
||||
case CANVAS_TOP_RIGHT:
|
||||
overlayPosition = OverlayPosition.TOP_RIGHT;
|
||||
break;
|
||||
case ABOVE_CHATBOX_RIGHT:
|
||||
overlayPosition = OverlayPosition.BOTTOM_RIGHT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
final OverlayPosition overlayPosition = getCorrectedOverlayPosition(overlay);
|
||||
|
||||
if (overlayPosition == OverlayPosition.DYNAMIC || overlayPosition == OverlayPosition.TOOLTIP)
|
||||
{
|
||||
@@ -345,6 +323,13 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
||||
{
|
||||
for (Overlay overlay : overlayManager.getOverlays())
|
||||
{
|
||||
final OverlayPosition overlayPosition = getCorrectedOverlayPosition(overlay);
|
||||
|
||||
if (overlayPosition == OverlayPosition.DYNAMIC || overlayPosition == OverlayPosition.TOOLTIP)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (overlay.getBounds().contains(mousePoint))
|
||||
{
|
||||
if (SwingUtilities.isRightMouseButton(mouseEvent))
|
||||
@@ -524,6 +509,35 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
|
||||
overlay.getBounds().setSize(dimension);
|
||||
}
|
||||
|
||||
private OverlayPosition getCorrectedOverlayPosition(final Overlay overlay)
|
||||
{
|
||||
OverlayPosition overlayPosition = overlay.getPosition();
|
||||
|
||||
if (overlay.getPreferredPosition() != null)
|
||||
{
|
||||
overlayPosition = overlay.getPreferredPosition();
|
||||
}
|
||||
|
||||
if (!isResizeable)
|
||||
{
|
||||
// On fixed mode, ABOVE_CHATBOX_RIGHT is in the same location as
|
||||
// BOTTOM_RIGHT and CANVAS_TOP_RIGHT is same as TOP_RIGHT.
|
||||
// Just use BOTTOM_RIGHT and TOP_RIGHT to prevent overlays from
|
||||
// drawing over each other.
|
||||
switch (overlayPosition)
|
||||
{
|
||||
case CANVAS_TOP_RIGHT:
|
||||
overlayPosition = OverlayPosition.TOP_RIGHT;
|
||||
break;
|
||||
case ABOVE_CHATBOX_RIGHT:
|
||||
overlayPosition = OverlayPosition.BOTTOM_RIGHT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return overlayPosition;
|
||||
}
|
||||
|
||||
private boolean shouldInvalidateBounds()
|
||||
{
|
||||
final Widget chatbox = client.getWidget(WidgetInfo.CHATBOX);
|
||||
|
||||
@@ -476,6 +476,7 @@ public class SwingUtil
|
||||
|
||||
public static void addModalTooltip(AbstractButton button, String on, String off)
|
||||
{
|
||||
button.setToolTipText(button.isSelected() ? on : off);
|
||||
button.addItemListener(l -> button.setToolTipText(button.isSelected() ? on : off));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user