astropanel 2.6 → 2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/astropanel +117 -23
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab87ddd7784d3b47b1a807f39f4a1116ef5498da9e1abed7aa83c77daae7e5a4
|
4
|
+
data.tar.gz: d2c5f209b93b9cd369ee056aa9d41e8b118f0c6137e99797cf58656c15bb8aab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18c52254d3c68c8f03797639d5d9cc8546a5824a8db17200fdd8345a3c53256232eec6058ff7d1fec4f55a2305dfac89c0db37f4f82eedf9698b8e978fb286b0
|
7
|
+
data.tar.gz: 9c7cb190ce0502763f5ef4ff16dd08ea11f6621f77b39555deb698f7d172b2ac6c4c647b937676a2208b8c630ed64b47f19c8ee5ceaab52b0dcc9cf900e569f0
|
data/bin/astropanel
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
# for any damages resulting from its use. Further, I am under no
|
15
15
|
# obligation to maintain or extend this software. It is provided
|
16
16
|
# on an 'as is' basis without any expressed or implied warranty.
|
17
|
-
# Version: 2.
|
17
|
+
# Version: 2.7: Image redraw fix for i3-wm workspace switching
|
18
18
|
|
19
19
|
# LOAD MODULES {{{1
|
20
20
|
require 'io/console'
|
@@ -33,6 +33,7 @@ include Rcurses::Cursor
|
|
33
33
|
# BASIC SETUP {{{1
|
34
34
|
CONFIG_FILE = File.join(Dir.home, '.ap.conf')
|
35
35
|
|
36
|
+
|
36
37
|
# CLASS EXTENSIONS {{{1
|
37
38
|
class Numeric # {{{2
|
38
39
|
def deg; self * Math::PI / 180; end
|
@@ -543,6 +544,34 @@ class AstroPanelApp
|
|
543
544
|
# allow override from ~/.ap.conf
|
544
545
|
@w3mimgdisplay ||= "/usr/lib/w3m/w3mimgdisplay"
|
545
546
|
@showimage = File.executable?(@w3mimgdisplay)
|
547
|
+
@current_image = nil
|
548
|
+
end
|
549
|
+
|
550
|
+
def check_image_redraw # {{{2
|
551
|
+
# Only check if image display is enabled
|
552
|
+
return unless @showimage
|
553
|
+
|
554
|
+
# Only check if we have an image currently displayed
|
555
|
+
return unless @current_image && File.exist?(@current_image)
|
556
|
+
|
557
|
+
begin
|
558
|
+
# Check if we're in the active window - if not, image overlay might be cleared
|
559
|
+
active_window = `xdotool getactivewindow 2>/dev/null`.chomp
|
560
|
+
return if active_window.empty?
|
561
|
+
|
562
|
+
# Check if this terminal window is the active one
|
563
|
+
current_window = `xdotool getwindowfocus 2>/dev/null`.chomp
|
564
|
+
|
565
|
+
# Only redraw if we detect a focus change (simple heuristic)
|
566
|
+
if @last_active_window && @last_active_window != active_window && current_window == active_window
|
567
|
+
# Window focus changed and we're now active - redraw image
|
568
|
+
show_image(@current_image)
|
569
|
+
end
|
570
|
+
|
571
|
+
@last_active_window = active_window
|
572
|
+
rescue
|
573
|
+
# Silently fail - we don't want focus checking to break anything
|
574
|
+
end
|
546
575
|
end
|
547
576
|
|
548
577
|
def show_image(file=nil) # {{{2
|
@@ -580,6 +609,12 @@ class AstroPanelApp
|
|
580
609
|
# Clear image area
|
581
610
|
`echo "6;#{px};#{py};#{max_w};#{max_h};\n4;\n3;" | #{@w3mimgdisplay} 2>/dev/null`
|
582
611
|
`echo "0;1;#{px};#{py};#{iw};#{ih};;;;;\"#{file}\"\n4;\n3;" | #{@w3mimgdisplay} 2>/dev/null`
|
612
|
+
|
613
|
+
# Track the current image
|
614
|
+
@current_image = file
|
615
|
+
else
|
616
|
+
# Clear image if no file or file doesn't exist
|
617
|
+
@current_image = nil
|
583
618
|
end
|
584
619
|
end
|
585
620
|
rescue Timeout::Error
|
@@ -659,13 +694,22 @@ class AstroPanelApp
|
|
659
694
|
@left = Pane.new( 2, 3, 70, rows - 3, 248, 232)
|
660
695
|
@main = Pane.new( 74, 3, cols - 74, rows - 4, 255, 232)
|
661
696
|
@footer = Pane.new( 1, cols, cols, 1, 255, 24)
|
697
|
+
|
698
|
+
# Add update attributes for selective rendering
|
699
|
+
[@header, @titles, @left, @main, @footer].each do |pane|
|
700
|
+
pane.define_singleton_method(:update) { @update }
|
701
|
+
pane.define_singleton_method(:update=) { |val| @update = val }
|
702
|
+
pane.update = false
|
703
|
+
end
|
662
704
|
end
|
663
705
|
|
664
706
|
def run_loop # {{{2
|
665
707
|
fetch_all
|
666
708
|
show_image(@current_image) if @current_image
|
709
|
+
@last_render_state = nil
|
710
|
+
@left.update = @main.update = @header.update = @footer.update = true
|
667
711
|
loop do
|
668
|
-
|
712
|
+
render_selective
|
669
713
|
handle_input
|
670
714
|
end
|
671
715
|
ensure
|
@@ -705,8 +749,51 @@ class AstroPanelApp
|
|
705
749
|
COND_COLORS[level]
|
706
750
|
end
|
707
751
|
|
752
|
+
def current_render_state # {{{2
|
753
|
+
[@index, @weather.size, @time, @today].hash
|
754
|
+
end
|
755
|
+
|
756
|
+
def needs_render? # {{{2
|
757
|
+
current_state = current_render_state
|
758
|
+
state_changed = @last_render_state != current_state
|
759
|
+
|
760
|
+
# Also check if any panes need updating
|
761
|
+
panes_need_update = @left.update || @main.update || @header.update || @footer.update
|
762
|
+
|
763
|
+
needs_update = state_changed || panes_need_update
|
764
|
+
@last_render_state = current_state if state_changed
|
765
|
+
needs_update
|
766
|
+
end
|
767
|
+
|
768
|
+
def render_selective # {{{2
|
769
|
+
return unless needs_render?
|
770
|
+
|
771
|
+
if @header.update
|
772
|
+
update_header
|
773
|
+
@header.update = false
|
774
|
+
end
|
775
|
+
|
776
|
+
if @footer.update
|
777
|
+
update_footer
|
778
|
+
@footer.update = false
|
779
|
+
end
|
780
|
+
|
781
|
+
if @left.update
|
782
|
+
update_left
|
783
|
+
@left.update = false
|
784
|
+
end
|
785
|
+
|
786
|
+
if @main.update
|
787
|
+
update_main
|
788
|
+
@main.update = false
|
789
|
+
end
|
790
|
+
|
791
|
+
update_titles # Always update titles as they're lightweight
|
792
|
+
end
|
793
|
+
|
708
794
|
def draw_all # {{{2
|
709
|
-
|
795
|
+
@header.update = @footer.update = @left.update = @main.update = true
|
796
|
+
render_selective
|
710
797
|
end
|
711
798
|
|
712
799
|
def update_header # {{{2
|
@@ -895,36 +982,43 @@ class AstroPanelApp
|
|
895
982
|
|
896
983
|
def handle_input # {{{2
|
897
984
|
old_index = @index
|
898
|
-
|
985
|
+
key = getchr(1) # 1 second timeout like rtfm
|
986
|
+
|
987
|
+
unless key # If timeout occurred (no key pressed)
|
988
|
+
check_image_redraw # Check if image needs redraw after workspace switch
|
989
|
+
return
|
990
|
+
end
|
991
|
+
|
992
|
+
case key
|
899
993
|
when 'UP' then @index = (@index - 1) % @weather.size
|
900
994
|
when 'DOWN' then @index = (@index + 1) % @weather.size
|
901
995
|
when 'PgUP' then @index = [@index - @left.h, 0].max
|
902
996
|
when 'PgDOWN' then @index = [@index + @left.h, @weather.size - 1].min
|
903
997
|
when 'HOME' then @index = 0
|
904
998
|
when 'END' then @index = @weather.size - 1
|
905
|
-
when '?' then @main.say(HELP); getchr
|
906
|
-
when 'l' then @loc = @footer.ask('Loc? ', @loc)
|
907
|
-
when 'a' then @lat = @footer.ask('Lat? ', @lat.to_s).to_f
|
908
|
-
when 'o' then @lon = @footer.ask('Lon? ', @lon.to_s).to_f
|
909
|
-
when 'c' then @cloudlimit = @footer.ask('Maximum Cloud coverage? ', @cloudlimit.to_s).to_i
|
910
|
-
when 'h' then @humiditylimit = @footer.ask('Maximum Humidity? ', @humiditylimit.to_s).to_i
|
911
|
-
when 't' then @templimit = @footer.ask('Minimum Temperature? ', @templimit.to_s).to_i
|
912
|
-
when 'w' then @windlimit = @footer.ask('Maximum Wind? ', @windlimit.to_s).to_i
|
913
|
-
when 'b' then @bortle = @footer.ask('Bortle? ', @bortle.to_s).to_f
|
914
|
-
when 'e' then show_all_events
|
915
|
-
when 's' then starchart
|
999
|
+
when '?' then @main.say(HELP); getchr; @main.update = true
|
1000
|
+
when 'l' then @loc = @footer.ask('Loc? ', @loc); @header.update = @footer.update = true
|
1001
|
+
when 'a' then @lat = @footer.ask('Lat? ', @lat.to_s).to_f; @header.update = @footer.update = true
|
1002
|
+
when 'o' then @lon = @footer.ask('Lon? ', @lon.to_s).to_f; @header.update = @footer.update = true
|
1003
|
+
when 'c' then @cloudlimit = @footer.ask('Maximum Cloud coverage? ', @cloudlimit.to_s).to_i; @footer.update = true
|
1004
|
+
when 'h' then @humiditylimit = @footer.ask('Maximum Humidity? ', @humiditylimit.to_s).to_i; @footer.update = true
|
1005
|
+
when 't' then @templimit = @footer.ask('Minimum Temperature? ', @templimit.to_s).to_i; @footer.update = true
|
1006
|
+
when 'w' then @windlimit = @footer.ask('Maximum Wind? ', @windlimit.to_s).to_i; @footer.update = true
|
1007
|
+
when 'b' then @bortle = @footer.ask('Bortle? ', @bortle.to_s).to_f; @footer.update = true
|
1008
|
+
when 'e' then show_all_events; @main.update = true
|
1009
|
+
when 's' then starchart; @main.update = true
|
916
1010
|
when 'S' then system("xdg-open /tmp/starchart.jpg &")
|
917
|
-
when 'A' then apod
|
918
|
-
when 'r' then refresh_all
|
919
|
-
when 'R' then fetch_all
|
920
|
-
when 'W' then save_config; @footer.say("Config saved"); getchr
|
1011
|
+
when 'A' then apod; @main.update = true
|
1012
|
+
when 'r' then refresh_all; @header.update = @left.update = @main.update = @footer.update = true
|
1013
|
+
when 'R' then fetch_all; @header.update = @left.update = @main.update = @footer.update = true
|
1014
|
+
when 'W' then save_config; @footer.say("Config saved"); getchr; @footer.update = true
|
921
1015
|
when 'q' then exit
|
922
1016
|
end
|
923
1017
|
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
1018
|
+
# Only update panes if index changed (for navigation keys)
|
1019
|
+
if @index != old_index
|
1020
|
+
@left.update = @main.update = true
|
1021
|
+
end
|
928
1022
|
end
|
929
1023
|
|
930
1024
|
def get_weather # {{{2
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: astropanel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '2.
|
4
|
+
version: '2.7'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Geir Isene
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-05
|
11
|
+
date: 2025-07-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rcurses
|
@@ -28,8 +28,8 @@ description: 'This program shows essential data in order to plan your observatio
|
|
28
28
|
9 days weather forecast, full ephemeris for the Sun, the Moon and all major planets,
|
29
29
|
complete with graphic representation of rise/set times, detailed info for each day
|
30
30
|
with important astronomical events, star chart displayed in the terminal and more.
|
31
|
-
New in 2.0: Full rewrite using rcurses (https://github.com/isene/rcurses). 2.
|
32
|
-
|
31
|
+
New in 2.0: Full rewrite using rcurses (https://github.com/isene/rcurses). 2.7:
|
32
|
+
Image redraw fix for i3-wm workspace switching.'
|
33
33
|
email: g@isene.com
|
34
34
|
executables:
|
35
35
|
- astropanel
|