fortrangoingonforty/fortty / 896305f

Browse files

Add window opacity and blur configuration options

Window appearance can now be configured via TOML:
- [window] opacity = 0.95 (0.0-1.0, default 1.0)
- [window] blur = true (macOS only, currently stubbed)

Implementation:
- Add toml_get_real() for float parsing in TOML
- Add window_opacity and window_blur to config_t
- Enable GLFW_TRANSPARENT_FRAMEBUFFER when opacity < 1.0
- Use opacity value in glClearColor alpha channel
- Add window_set_blur() function (stub - needs Cocoa integration)

Note: macOS blur requires Cocoa framework which has CMake integration
issues with Fortran compilers. The blur function is stubbed for now.
Authored by espadonne
SHA
896305f42ffee14531a838b719b0f5609b715aa8
Parents
c65ecb0
Tree
eb648dd

7 changed files

StatusFile+-
M CMakeLists.txt 22 2
M c_src/pty_helpers.c 10 0
M src/config/config.f90 6 0
M src/config/toml_parser.f90 20 1
M src/fortty.f90 9 4
M src/window/glfw_bindings.f90 1 0
M src/window/window.f90 31 2
CMakeLists.txtmodified
@@ -22,12 +22,17 @@ if(PkgConfig_FOUND)
2222
 endif()
2323
 
2424
 # C helper libraries (GLAD + FreeType + PTY wrappers)
25
-add_library(helpers STATIC
25
+set(HELPER_SOURCES
2626
     src/gl/glad.c
2727
     c_src/gl_loader.c
2828
     c_src/freetype_helpers.c
2929
     c_src/pty_helpers.c
3030
 )
31
+
32
+# macOS window helpers placeholder - blur requires Cocoa which conflicts with Fortran build
33
+# TODO: Enable when CMake framework flag issue is resolved
34
+
35
+add_library(helpers STATIC ${HELPER_SOURCES})
3136
 target_include_directories(helpers PUBLIC ${CMAKE_SOURCE_DIR}/include)
3237
 target_include_directories(helpers PRIVATE ${FREETYPE_INCLUDE_DIRS})
3338
 target_link_libraries(helpers PRIVATE glfw ${FREETYPE_LIBRARIES})
@@ -37,6 +42,8 @@ if(UNIX AND NOT APPLE)
3742
     target_link_libraries(helpers PRIVATE util)
3843
 endif()
3944
 
45
+# Note: Cocoa framework linked at executable level to avoid flag conflicts with Fortran
46
+
4047
 # Link fontconfig if available
4148
 if(FONTCONFIG_FOUND)
4249
     target_compile_definitions(helpers PRIVATE HAVE_FONTCONFIG)
@@ -80,7 +87,18 @@ set(FORTRAN_SOURCES
8087
 # Main executable
8188
 add_executable(fortty ${FORTRAN_SOURCES})
8289
 target_include_directories(fortty PRIVATE ${CMAKE_BINARY_DIR}/modules)
83
-target_link_libraries(fortty PRIVATE helpers glfw OpenGL::GL ${FREETYPE_LIBRARIES})
90
+
91
+# Work around CMake framework flag issue: flang doesn't understand -F flag
92
+if(APPLE)
93
+    # Remove -F flags from Fortran compile options
94
+    string(REPLACE "-F/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks" ""
95
+           CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}")
96
+    # Also set a compile option filter for the target
97
+    set_target_properties(fortty PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "")
98
+endif()
99
+
100
+# Link libraries - glfw linked through helpers
101
+target_link_libraries(fortty PRIVATE helpers OpenGL::GL ${FREETYPE_LIBRARIES})
84102
 
85103
 # Add fontconfig link directory if available (needed for linker to find it)
86104
 if(FONTCONFIG_FOUND)
@@ -91,3 +109,5 @@ endif()
91109
 if(UNIX AND NOT APPLE)
92110
     target_link_libraries(fortty PRIVATE dl)
93111
 endif()
112
+
113
+# TODO: Link Cocoa framework for blur when CMake framework flag issue is resolved
c_src/pty_helpers.cmodified
@@ -202,3 +202,13 @@ int fortty_pty_child_alive(void) {
202202
 int fortty_pty_get_child_pid(void) {
203203
     return (int)child_pid;
204204
 }
205
+
206
+/*
207
+ * Window blur stub - macOS blur requires Cocoa framework which has
208
+ * CMake integration issues with Fortran. This is a no-op placeholder.
209
+ * TODO: Implement with NSVisualEffectView when build system supports it.
210
+ */
211
+void fortty_set_window_blur(void* window, int enable) {
212
+    (void)window;
213
+    (void)enable;
214
+}
src/config/config.f90modified
@@ -11,6 +11,8 @@ module config_mod
1111
     ! Window
1212
     integer :: window_width = 800
1313
     integer :: window_height = 600
14
+    real :: window_opacity = 1.0      ! 0.0 (transparent) to 1.0 (opaque)
15
+    logical :: window_blur = .false.  ! macOS only: enable background blur
1416
 
1517
     ! Font
1618
     character(len=256) :: font_path = ''       ! Empty = use fontconfig
@@ -41,6 +43,8 @@ contains
4143
 
4244
     cfg%window_width = 800
4345
     cfg%window_height = 600
46
+    cfg%window_opacity = 1.0
47
+    cfg%window_blur = .false.
4448
 
4549
     cfg%font_path = ''
4650
     cfg%font_fallback = ''
@@ -133,6 +137,8 @@ contains
133137
     ! Window settings
134138
     cfg%window_width = toml_get_integer(tf, 'window', 'width', cfg%window_width)
135139
     cfg%window_height = toml_get_integer(tf, 'window', 'height', cfg%window_height)
140
+    cfg%window_opacity = toml_get_real(tf, 'window', 'opacity', cfg%window_opacity)
141
+    cfg%window_blur = toml_get_logical(tf, 'window', 'blur', cfg%window_blur)
136142
 
137143
     ! Font settings
138144
     str_val = toml_get_string(tf, 'font', 'family', '')
src/config/toml_parser.f90modified
@@ -4,7 +4,7 @@ module toml_parser_mod
44
 
55
   public :: toml_file_t
66
   public :: toml_open, toml_close
7
-  public :: toml_get_string, toml_get_integer, toml_get_logical
7
+  public :: toml_get_string, toml_get_integer, toml_get_real, toml_get_logical
88
 
99
   integer, parameter :: MAX_LINE_LEN = 512
1010
   integer, parameter :: MAX_KEYS = 128
@@ -187,6 +187,25 @@ contains
187187
 
188188
   end function toml_get_integer
189189
 
190
+  ! Get a real value from the TOML file
191
+  function toml_get_real(tf, section, key, default) result(val)
192
+    type(toml_file_t), intent(in) :: tf
193
+    character(len=*), intent(in) :: section, key
194
+    real, intent(in) :: default
195
+    real :: val
196
+    character(len=256) :: str_val
197
+    integer :: ios
198
+
199
+    val = default
200
+    str_val = toml_get_string(tf, section, key, '')
201
+
202
+    if (len_trim(str_val) > 0) then
203
+      read(str_val, *, iostat=ios) val
204
+      if (ios /= 0) val = default
205
+    end if
206
+
207
+  end function toml_get_real
208
+
190209
   ! Get a logical value from the TOML file
191210
   function toml_get_logical(tf, section, key, default) result(val)
192211
     type(toml_file_t), intent(in) :: tf
src/fortty.f90modified
@@ -51,8 +51,13 @@ program fortty
5151
   win_width = cfg%window_width
5252
   win_height = cfg%window_height
5353
 
54
-  ! Create window with OpenGL context
55
-  win = window_create(win_width, win_height, "fortty")
54
+  ! Create window with OpenGL context (enable transparency if opacity < 1.0)
55
+  win = window_create(win_width, win_height, "fortty", cfg%window_opacity < 1.0)
56
+
57
+  ! Enable background blur if configured (macOS only)
58
+  if (cfg%window_blur) then
59
+    call window_set_blur(win, .true.)
60
+  end if
5661
 
5762
   ! Font path - use config if specified, otherwise fontconfig, then fallbacks
5863
   if (len_trim(cfg%font_path) > 0) then
@@ -258,11 +263,11 @@ program fortty
258263
       call window_set_title(win, terminal_get_title(term))
259264
     end if
260265
 
261
-    ! Clear screen with background color from config
266
+    ! Clear screen with background color and opacity from config
262267
     bg_r = real(cfg%bg_color%r) / 255.0
263268
     bg_g = real(cfg%bg_color%g) / 255.0
264269
     bg_b = real(cfg%bg_color%b) / 255.0
265
-    call glClearColor(bg_r, bg_g, bg_b, 1.0)
270
+    call glClearColor(bg_r, bg_g, bg_b, cfg%window_opacity)
266271
     call glClear(GL_COLOR_BUFFER_BIT)
267272
 
268273
     ! Render terminal buffer
src/window/glfw_bindings.f90modified
@@ -14,6 +14,7 @@ module glfw_bindings
1414
   integer(c_int), parameter :: GLFW_OPENGL_PROFILE = int(Z'00022008', c_int)
1515
   integer(c_int), parameter :: GLFW_OPENGL_CORE_PROFILE = int(Z'00032001', c_int)
1616
   integer(c_int), parameter :: GLFW_OPENGL_FORWARD_COMPAT = int(Z'00022006', c_int)
17
+  integer(c_int), parameter :: GLFW_TRANSPARENT_FRAMEBUFFER = int(Z'0002000A', c_int)
1718
 
1819
   ! Key constants
1920
   integer(c_int), parameter :: GLFW_KEY_ESCAPE = 256
src/window/window.f90modified
@@ -13,7 +13,7 @@ module window_mod
1313
   public :: window_create, window_destroy
1414
   public :: window_should_close, window_swap_buffers, window_poll_events
1515
   public :: window_get_size, window_set_pty, window_set_terminal
16
-  public :: window_set_title, window_set_cell_size
16
+  public :: window_set_title, window_set_cell_size, window_set_blur
1717
   public :: window_get_selection, window_clipboard_set, window_clipboard_get
1818
 
1919
   type :: window_t
@@ -45,13 +45,21 @@ module window_mod
4545
     integer(c_int) function fortty_load_gl() bind(C, name="fortty_load_gl")
4646
       import :: c_int
4747
     end function fortty_load_gl
48
+
49
+    ! macOS window blur (no-op on other platforms)
50
+    subroutine fortty_set_window_blur_c(window, enable) bind(C, name="fortty_set_window_blur")
51
+      import :: c_ptr, c_int
52
+      type(c_ptr), value :: window
53
+      integer(c_int), value :: enable
54
+    end subroutine fortty_set_window_blur_c
4855
   end interface
4956
 
5057
 contains
5158
 
52
-  function window_create(width, height, title) result(win)
59
+  function window_create(width, height, title, transparent) result(win)
5360
     integer, intent(in) :: width, height
5461
     character(len=*), intent(in) :: title
62
+    logical, intent(in), optional :: transparent
5563
     type(window_t) :: win
5664
     type(c_funptr) :: dummy
5765
     integer(c_int) :: gl_loaded
@@ -72,6 +80,13 @@ contains
7280
     call glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
7381
     call glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE)
7482
 
83
+    ! Enable transparent framebuffer if requested (for window opacity)
84
+    if (present(transparent)) then
85
+      if (transparent) then
86
+        call glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE)
87
+      end if
88
+    end if
89
+
7590
     ! Create window
7691
     c_title = trim(title) // c_null_char
7792
     win%handle = glfwCreateWindow(width, height, c_title, c_null_ptr, c_null_ptr)
@@ -477,6 +492,20 @@ contains
477492
     call glfwSetWindowTitle(win%handle, c_title)
478493
   end subroutine window_set_title
479494
 
495
+  ! Enable background blur (macOS only, no-op on other platforms)
496
+  subroutine window_set_blur(win, enable)
497
+    type(window_t), intent(in) :: win
498
+    logical, intent(in) :: enable
499
+
500
+    if (.not. c_associated(win%handle)) return
501
+
502
+    if (enable) then
503
+      call fortty_set_window_blur_c(win%handle, 1_c_int)
504
+    else
505
+      call fortty_set_window_blur_c(win%handle, 0_c_int)
506
+    end if
507
+  end subroutine window_set_blur
508
+
480509
   ! Set cell dimensions for mouse coordinate conversion
481510
   subroutine window_set_cell_size(w, h)
482511
     integer, intent(in) :: w, h