Compare commits
4 Commits
feat/ui_ll
...
ee76f9d89f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee76f9d89f | ||
|
|
37cc29e4cd | ||
|
|
180afb1336 | ||
| 0c88272bf0 |
@@ -2,11 +2,12 @@
|
|||||||
|
|
||||||
## MinGW/WinLibs для Fyne-сборки на Windows
|
## MinGW/WinLibs для Fyne-сборки на Windows
|
||||||
- UI (internal/ui/desktop, fyne.io/fyne/v2) требует cgo + C-компилятор для GLFW.
|
- UI (internal/ui/desktop, fyne.io/fyne/v2) требует cgo + C-компилятор для GLFW.
|
||||||
- Используется **WinLibs** (mingw64) gcc. Bin каталог нужно добавить в PATH перед
|
- Установлен постоянно в `D:\MinGW\bin` (WinLibs x86_64-ucrt-posix-seh, GCC 16.2.0),
|
||||||
`scripts/build-publish-ui.ps1`:
|
файл `D:\MinGW\bin\gcc.exe` существует. НО каталог не гарантированно в PATH текущей
|
||||||
```powershell
|
сессии (проверено 2026-08-21: `D:\MinGW\bin` отсутствовал в PATH, `gcc` не находился).
|
||||||
$p = "<...>\mingw64\bin"; $env:Path = "$p;$env:Path"
|
`scripts/build-publish-ui.ps1` сам проверяет gcc и при отсутствии подсказывает ручную
|
||||||
```
|
подстановку PATH (стр. 36–41): `$env:Path = "<...>\mingw64\bin;$env:Path"`.
|
||||||
|
- Прежняя winget-версия (BrechtSanders.WinLibs.POSIX.UCRT) удалена, чтобы не было дубликата.
|
||||||
- Проверка: `gcc --version`; также убедиться, что `CGO_ENABLED` не = "0".
|
- Проверка: `gcc --version`; также убедиться, что `CGO_ENABLED` не = "0".
|
||||||
- Care: не использовать Cygwin/MSYS-сборки gcc — только native MinGW-w64 (WinLibs).
|
- Care: не использовать Cygwin/MSYS-сборки gcc — только native MinGW-w64 (WinLibs).
|
||||||
- Сборка UI выполняется локально на Windows-машине, публикуется в Gitea Packages
|
- Сборка UI выполняется локально на Windows-машине, публикуется в Gitea Packages
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ func (p *ChatPanel) Composer() fyne.CanvasObject {
|
|||||||
widget.NewButton("Пропустить", func() { if p.commands != nil { p.commands.Skip() } }),
|
widget.NewButton("Пропустить", func() { if p.commands != nil { p.commands.Skip() } }),
|
||||||
widget.NewButton("Отмена", func() { if p.commands != nil { p.commands.Cancel() } }),
|
widget.NewButton("Отмена", func() { if p.commands != nil { p.commands.Cancel() } }),
|
||||||
)
|
)
|
||||||
return container.NewBorder(nil, nil, cmdBar, p.input, nil)
|
return container.NewBorder(nil, nil, cmdBar, nil, p.input)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTranscript заменяет содержимое диалога (спец 12.12).
|
// SetTranscript заменяет содержимое диалога (спец 12.12).
|
||||||
|
|||||||
48
internal/ui/desktop/maximize_windows.go
Normal file
48
internal/ui/desktop/maximize_windows.go
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
//go:build cgo
|
||||||
|
|
||||||
|
package desktop
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Нативный максимум окна через Win32.
|
||||||
|
//
|
||||||
|
// Fyne (v2.6) не даёт ни Move, ни Maximize у fyne.Window, поэтому разворот на
|
||||||
|
// экран (над панелью задач) делаем напрямую через user32: находим HWND нашего
|
||||||
|
// процесса через EnumWindows и вызываем ShowWindow(SW_MAXIMIZE).
|
||||||
|
// Только Windows (платформа приложения по спеке — Windows).
|
||||||
|
|
||||||
|
const (
|
||||||
|
swMaximize = 9
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
user32 = syscall.NewLazyDLL("user32.dll")
|
||||||
|
procEnumWindows = user32.NewProc("EnumWindows")
|
||||||
|
procGetWindowThreadProcID = user32.NewProc("GetWindowThreadProcessId")
|
||||||
|
procIsWindowVisible = user32.NewProc("IsWindowVisible")
|
||||||
|
procShowWindow = user32.NewProc("ShowWindow")
|
||||||
|
)
|
||||||
|
|
||||||
|
func maximizeWindow() {
|
||||||
|
pid := uint32(os.Getpid())
|
||||||
|
|
||||||
|
cb := syscall.NewCallback(func(hwnd syscall.Handle, _ uintptr) uintptr {
|
||||||
|
var winPid uint32
|
||||||
|
procGetWindowThreadProcID.Call(uintptr(hwnd), uintptr(unsafe.Pointer(&winPid)))
|
||||||
|
if winPid != pid {
|
||||||
|
return 1 // continue перечисление
|
||||||
|
}
|
||||||
|
visible, _, _ := procIsWindowVisible.Call(uintptr(hwnd))
|
||||||
|
if visible == 0 {
|
||||||
|
return 1 // continue перечисление
|
||||||
|
}
|
||||||
|
procShowWindow.Call(uintptr(hwnd), swMaximize)
|
||||||
|
return 0 // остановить перечисление
|
||||||
|
})
|
||||||
|
|
||||||
|
procEnumWindows.Call(cb, 0)
|
||||||
|
}
|
||||||
@@ -72,7 +72,6 @@ func New(appID string, store ui.Store) *Window {
|
|||||||
tabSession: map[*container.TabItem]*ui.Session{},
|
tabSession: map[*container.TabItem]*ui.Session{},
|
||||||
}
|
}
|
||||||
w.win = fa.NewWindow("Ratatoskr")
|
w.win = fa.NewWindow("Ratatoskr")
|
||||||
w.win.SetFullScreen(true)
|
|
||||||
w.build()
|
w.build()
|
||||||
w.win.SetCloseIntercept(func() {
|
w.win.SetCloseIntercept(func() {
|
||||||
// Закрытие окна = сворачивание (спец 12.6): Core продолжает работать.
|
// Закрытие окна = сворачивание (спец 12.6): Core продолжает работать.
|
||||||
@@ -325,6 +324,7 @@ func (w *Window) OnMessage(h chat.Handler) { w.handler = h }
|
|||||||
// Run показывает окно и запускает Fyne-цикл. Блокирует до Quit.
|
// Run показывает окно и запускает Fyne-цикл. Блокирует до Quit.
|
||||||
func (w *Window) Run(ctx context.Context) error {
|
func (w *Window) Run(ctx context.Context) error {
|
||||||
w.win.Show()
|
w.win.Show()
|
||||||
|
maximizeWindow()
|
||||||
go func() {
|
go func() {
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
w.fyneApp.Quit()
|
w.fyneApp.Quit()
|
||||||
|
|||||||
Reference in New Issue
Block a user