diff --git a/i38.sh b/i38.sh index fa1ecc4..00566e3 100755 --- a/i38.sh +++ b/i38.sh @@ -825,6 +825,10 @@ focus_follows_mouse no # is used in the bar {} block below. font pango:monospace 8 +# Window rules +# Fix Wine window issues - improves stability and prevents lockups +for_window [class="Wine"] floating enable + # I38 help - Open comprehensive HTML guide bindsym \$mod+Shift+F1 exec $webBrowser ${i3Path}/I38.html diff --git a/scripts/sound.py b/scripts/sound.py index a360fb8..809803f 100755 --- a/scripts/sound.py +++ b/scripts/sound.py @@ -13,44 +13,73 @@ import i3ipc from i3ipc import Event -from os import system +import subprocess +import shlex #This script allows for sounds in i3 i3 = i3ipc.Connection() # Track the current mode so we know what we're exiting from currentMode = 'default' +def play_sound_async(command): + """Play a sound asynchronously without blocking i3's event loop""" + try: + subprocess.Popen( + command, + shell=True, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + start_new_session=True + ) + except Exception: + # Silently ignore sound playback errors to avoid blocking i3 + pass + def on_new_window(self,i3): - if i3.container.name == 'xfce4-notifyd': - system('play -nqV0 synth .05 sq 1800 tri 2400 delay 0 .03 remix - repeat 2 echo .55 0.7 20 1 norm -12 &') - else: - system('play -nqV0 synth .25 sin 440:880 sin 480:920 remix - norm -3 pitch -500 &') + try: + windowName = getattr(i3.container, 'name', None) + windowClass = getattr(i3.container, 'window_class', None) + # Special notification sound for notification daemon (it has its own sound) + if windowName == 'xfce4-notifyd' or windowClass == 'xfce4-notifyd': + play_sound_async('play -nqV0 synth .05 sq 1800 tri 2400 delay 0 .03 remix - repeat 2 echo .55 0.7 20 1 norm -12') + else: + play_sound_async('play -nqV0 synth .25 sin 440:880 sin 480:920 remix - norm -3 pitch -500') + except Exception: + # Silently ignore errors to prevent blocking i3 + pass def on_close_window(self,i3): - if i3.container.name != 'xfce4-notifyd': - system('play -nqV0 synth .25 sin 880:440 sin 920:480 remix - norm -3 pitch -500 &') + try: + windowName = getattr(i3.container, 'name', None) + windowClass = getattr(i3.container, 'window_class', None) + # Skip sound only for notification daemon (it has its own sound) + if windowName != 'xfce4-notifyd' and windowClass != 'xfce4-notifyd': + play_sound_async('play -nqV0 synth .25 sin 880:440 sin 920:480 remix - norm -3 pitch -500') + except Exception: + # Silently ignore errors to prevent blocking i3 + pass def on_mode(self,event): global currentMode mode = event.change if mode == 'ratpoison': - system('play -qV0 "|sox -np synth .07 sq 400" "|sox -np synth .5 sq 800" fade h 0 .5 .5 norm -20 &') + play_sound_async('play -qV0 "|sox -np synth .07 sq 400" "|sox -np synth .5 sq 800" fade h 0 .5 .5 norm -20') elif mode == 'bypass': - system('play -nqV0 synth .1 saw 700 saw 1200 delay 0 .04 remix - norm -6') + play_sound_async('play -nqV0 synth .1 saw 700 saw 1200 delay 0 .04 remix - norm -6') elif mode == 'default': # Play different sounds based on which mode we're exiting if currentMode == 'ratpoison': - system('play -qV0 "|sox -np synth .07 sq 400" "|sox -np synth .5 sq 800" fade h 0 .5 .5 norm -20 reverse &') + play_sound_async('play -qV0 "|sox -np synth .07 sq 400" "|sox -np synth .5 sq 800" fade h 0 .5 .5 norm -20 reverse') elif currentMode == 'panel': - system('play -nqV0 synth 0.05 pluck C5 norm -8 : synth 0.05 pluck F4 norm -8 : synth 0.05 pluck C4 norm -8 : synth 0.05 pluck F3 norm -8 &') + play_sound_async('play -nqV0 synth 0.05 pluck C5 norm -8 : synth 0.05 pluck F4 norm -8 : synth 0.05 pluck C4 norm -8 : synth 0.05 pluck F3 norm -8') elif currentMode == 'bypass': - system('play -nqV0 synth .1 saw 1200 saw 700 delay 0 .04 remix - norm -6 &') + play_sound_async('play -nqV0 synth .1 saw 1200 saw 700 delay 0 .04 remix - norm -6') else: # Generic exit sound for any other mode - system('play -qV0 "|sox -np synth .07 sq 400" "|sox -np synth .5 sq 800" fade h 0 .5 .5 norm -20 reverse &') + play_sound_async('play -qV0 "|sox -np synth .07 sq 400" "|sox -np synth .5 sq 800" fade h 0 .5 .5 norm -20 reverse') else: # Entering panel or any other mode - system('play -nqV0 synth 0.05 pluck F3 norm -8 : synth 0.05 pluck C4 norm -8 : synth 0.05 pluck F4 norm -8 : synth 0.05 pluck C5 norm -8 &') + play_sound_async('play -nqV0 synth 0.05 pluck F3 norm -8 : synth 0.05 pluck C4 norm -8 : synth 0.05 pluck F4 norm -8 : synth 0.05 pluck C5 norm -8') # Update current mode tracker currentMode = mode @@ -60,16 +89,16 @@ def on_workspace_focus(self,i3): pass def on_workspace_move(self,i3): - system('play -qnV0 synth pi fade 0 .25 .15 pad 0 1 reverb overdrive riaa norm -8 speed 1 reverse &') + play_sound_async('play -qnV0 synth pi fade 0 .25 .15 pad 0 1 reverb overdrive riaa norm -8 speed 1 reverse') def on_restart(self,i3): - system('play -qnV0 synth .25 saw 500:1200 fade .1 .25 .1 norm -8 &') + play_sound_async('play -qnV0 synth .25 saw 500:1200 fade .1 .25 .1 norm -8') def on_exit(self,i3): - system('play -qnV0 synth .3 sin 700:200 fade 0 .3 0 &') + play_sound_async('play -qnV0 synth .3 sin 700:200 fade 0 .3 0') def on_fullscreen(self,i3): - system('play -qnV0 synth br flanger fade h .3 .3 0 &') + play_sound_async('play -qnV0 synth br flanger fade h .3 .3 0') i3 = i3ipc.Connection()