Skip to content

Commit

Permalink
perf: use goroutine to implement window resize events.
Browse files Browse the repository at this point in the history
perf: optimized window display in fullscreen and maximized modes. tiny-craft#19
  • Loading branch information
tiny-craft committed Oct 15, 2023
1 parent 2db858b commit ad9f13d
Show file tree
Hide file tree
Showing 11 changed files with 225 additions and 95 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ frontend/wailsjs
design/
.vscode
.idea
test
10 changes: 6 additions & 4 deletions backend/services/preferences_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,12 @@ func (p *preferencesService) GetAppVersion() (resp types.JSResp) {
}

func (p *preferencesService) SaveWindowSize(width, height int) {
p.UpdatePreferences(map[string]any{
"behavior.windowWidth": width,
"behavior.windowHeight": height,
})
if width >= consts.DEFAULT_WINDOW_WIDTH && height >= consts.DEFAULT_WINDOW_HEIGHT {
p.UpdatePreferences(map[string]any{
"behavior.windowWidth": width,
"behavior.windowHeight": height,
})
}
}

func (p *preferencesService) GetWindowSize() (width, height int) {
Expand Down
47 changes: 0 additions & 47 deletions backend/services/system_dialog.go

This file was deleted.

105 changes: 105 additions & 0 deletions backend/services/system_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package services

import (
"context"
"github.com/wailsapp/wails/v2/pkg/runtime"
"log"
"sync"
"time"
"tinyrdm/backend/types"
)

type systemService struct {
ctx context.Context
}

var system *systemService
var onceSystem sync.Once

func System() *systemService {
if system == nil {
onceSystem.Do(func() {
system = &systemService{}
go system.loopWindowEvent()
})
}
return system
}

func (s *systemService) Start(ctx context.Context) {
s.ctx = ctx
}

// SelectFile open file dialog to select a file
func (s *systemService) SelectFile(title string) (resp types.JSResp) {
filepath, err := runtime.OpenFileDialog(s.ctx, runtime.OpenDialogOptions{
Title: title,
ShowHiddenFiles: true,
})
if err != nil {
log.Println(err)
resp.Msg = err.Error()
return
}
resp.Success = true
resp.Data = map[string]any{
"path": filepath,
}
return
}

func (s *systemService) loopWindowEvent() {
var fullscreen, maximised, minimised, normal bool
var width, height int
var dirty bool
for {
time.Sleep(300 * time.Millisecond)
if s.ctx == nil {
continue
}

dirty = false
if f := runtime.WindowIsFullscreen(s.ctx); f != fullscreen {
// full-screen switched
fullscreen = f
dirty = true
}

if w, h := runtime.WindowGetSize(s.ctx); w != width || h != height {
// window size changed
width, height = w, h
dirty = true
}

if m := runtime.WindowIsMaximised(s.ctx); m != maximised {
maximised = m
dirty = true
}

if m := runtime.WindowIsMinimised(s.ctx); m != minimised {
minimised = m
dirty = true
}

if n := runtime.WindowIsNormal(s.ctx); n != normal {
normal = n
dirty = true
}

if dirty {
runtime.EventsEmit(s.ctx, "window_changed", map[string]any{
"fullscreen": fullscreen,
"width": width,
"height": height,
"maximised": maximised,
"minimised": minimised,
"normal": normal,
})

if !fullscreen && !minimised {
// save window size
Preferences().SaveWindowSize(width, height)
}
}
}
}
73 changes: 55 additions & 18 deletions frontend/src/AppContent.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup>
import ContentPane from './components/content/ContentPane.vue'
import BrowserPane from './components/sidebar/BrowserPane.vue'
import { computed, reactive, ref, watch } from 'vue'
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { debounce, get } from 'lodash'
import { useThemeVars } from 'naive-ui'
import NavMenu from './components/sidebar/NavMenu.vue'
Expand All @@ -13,7 +13,7 @@ import useConnectionStore from './stores/connections.js'
import ContentLogPane from './components/content/ContentLogPane.vue'
import ContentValueTab from '@/components/content/ContentValueTab.vue'
import ToolbarControlWidget from '@/components/common/ToolbarControlWidget.vue'
import { WindowIsFullscreen, WindowToggleMaximise } from 'wailsjs/runtime/runtime.js'
import { EventsOn, WindowIsFullscreen, WindowIsMaximised, WindowToggleMaximise } from 'wailsjs/runtime/runtime.js'
import { isMacOS } from '@/utils/platform.js'
import iconUrl from '@/assets/images/icon.png'
Expand All @@ -37,19 +37,18 @@ const logPaneRef = ref(null)
// const preferences = ref({})
// provide('preferences', preferences)
const saveWidth = debounce(prefStore.savePreferences, 1000, { trailing: true })
const saveSidebarWidth = debounce(prefStore.savePreferences, 1000, { trailing: true })
const handleResize = (evt) => {
if (data.resizing) {
prefStore.setAsideWidth(Math.max(evt.clientX - data.navMenuWidth, 300))
saveWidth()
saveSidebarWidth()
}
}
const stopResize = () => {
data.resizing = false
document.removeEventListener('mousemove', handleResize)
document.removeEventListener('mouseup', stopResize)
// TODO: Save sidebar x-position
}
const startResize = () => {
Expand All @@ -75,28 +74,62 @@ watch(
},
)
const borderRadius = computed(() => {
// FIXME: cannot get full screen status sync?
// if (isMacOS()) {
// return WindowIsFullscreen().then((full) => {
// return full ? '0' : '10px'
// })
// }
return '10px'
})
const border = computed(() => {
const color = isMacOS() && false ? '#0000' : themeVars.value.borderColor
return `1px solid ${color}`
})
const borderRadius = ref(10)
const logoPaddingLeft = ref(10)
const maximised = ref(false)
const toggleWindowRadius = (on) => {
borderRadius.value = on ? 10 : 0
}
const onToggleFullscreen = (fullscreen) => {
if (fullscreen) {
logoPaddingLeft.value = 10
toggleWindowRadius(false)
} else {
logoPaddingLeft.value = isMacOS() ? 70 : 10
toggleWindowRadius(true)
}
}
const onToggleMaximize = (isMaximised) => {
if (isMaximised) {
maximised.value = true
if (!isMacOS()) {
toggleWindowRadius(false)
}
} else {
maximised.value = false
if (!isMacOS()) {
toggleWindowRadius(true)
}
}
}
EventsOn('window_changed', (info) => {
const { fullscreen, maximised } = info
onToggleFullscreen(fullscreen === true)
onToggleMaximize(maximised)
})
onMounted(async () => {
const fullscreen = await WindowIsFullscreen()
onToggleFullscreen(fullscreen === true)
const maximised = await WindowIsMaximised()
onToggleMaximize(maximised)
})
</script>
<template>
<!-- app content-->
<n-spin
:show="props.loading"
:theme-overrides="{ opacitySpinning: 0 }"
:style="{ backgroundColor: themeVars.bodyColor, borderRadius, border }">
:style="{ backgroundColor: themeVars.bodyColor, borderRadius: `${borderRadius}px`, border }">
<div
id="app-content-wrapper"
class="flex-box-v"
Expand All @@ -116,7 +149,7 @@ const border = computed(() => {
id="app-toolbar-title"
:style="{
width: `${data.navMenuWidth + prefStore.behavior.asideWidth - 4}px`,
paddingLeft: isMacOS() ? '70px' : '10px',
paddingLeft: `${logoPaddingLeft}px`,
}">
<n-space align="center" :wrap-item="false" :wrap="false" :size="3">
<n-avatar :src="iconUrl" color="#0000" :size="35" style="min-width: 35px" />
Expand All @@ -143,7 +176,11 @@ const border = computed(() => {
</div>
<div class="flex-item-expand"></div>
<!-- simulate window control buttons -->
<toolbar-control-widget v-if="!isMacOS()" :size="data.toolbarHeight" style="align-self: flex-start" />
<toolbar-control-widget
v-if="!isMacOS()"
:size="data.toolbarHeight"
:maximised="maximised"
style="align-self: flex-start" />
</div>
<!-- content -->
Expand Down
22 changes: 17 additions & 5 deletions frontend/src/components/common/ToolbarControlWidget.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ import WindowMax from '@/components/icons/WindowMax.vue'
import WindowClose from '@/components/icons/WindowClose.vue'
import { computed } from 'vue'
import { useThemeVars } from 'naive-ui'
import { Quit, WindowIsMaximised, WindowMinimise, WindowToggleMaximise } from 'wailsjs/runtime/runtime.js'
import { Quit, WindowMinimise, WindowToggleMaximise } from 'wailsjs/runtime/runtime.js'
import WindowRestore from '@/components/icons/WindowRestore.vue'
const themeVars = useThemeVars()
const props = defineProps({
size: {
type: Number,
default: 35,
},
maximised: {
type: Boolean,
},
})
const buttonSize = computed(() => {
Expand All @@ -33,23 +37,31 @@ const handleClose = () => {

<template>
<n-space :wrap-item="false" align="center" justify="center" :size="0">
<n-tooltip :show-arrow="false">
<n-tooltip :show-arrow="false" :delay="1000">
{{ $t('menu.minimise') }}
<template #trigger>
<div class="btn-wrapper" @click="handleMinimise">
<window-min />
</div>
</template>
</n-tooltip>
<n-tooltip :show-arrow="false">
{{ WindowIsMaximised() ? $t('menu.restore') : $t('menu.maximise') }}
<n-tooltip :show-arrow="false" :delay="1000" v-if="maximised">
{{ $t('menu.restore') }}
<template #trigger>
<div class="btn-wrapper" @click="handleMaximise">
<window-restore />
</div>
</template>
</n-tooltip>
<n-tooltip :show-arrow="false" :delay="1000" v-else>
{{ $t('menu.maximise') }}
<template #trigger>
<div class="btn-wrapper" @click="handleMaximise">
<window-max />
</div>
</template>
</n-tooltip>
<n-tooltip :show-arrow="false">
<n-tooltip :show-arrow="false" :delay="1000">
{{ $t('menu.close') }}
<template #trigger>
<div class="btn-wrapper" @click="handleClose">
Expand Down
10 changes: 4 additions & 6 deletions frontend/src/components/icons/WindowClose.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@
const props = defineProps({
size: {
type: [Number, String],
default: 12,
default: 14,
},
})
</script>

<template>
<svg aria-hidden="false" :width="props.size" :height="props.size" viewBox="0 0 12 12">
<polygon
fill="currentColor"
fill-rule="evenodd"
points="11 1.576 6.583 6 11 10.424 10.424 11 6 6.583 1.576 11 1 10.424 5.417 6 1 1.576 1.576 1 6 5.417 10.424 1"></polygon>
<svg :width="props.size" :height="props.size" viewBox="0 0 48 48" fill="none">
<path d="M8 8L40 40" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
<path d="M8 40L40 8" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
</svg>
</template>

Expand Down
Loading

0 comments on commit ad9f13d

Please sign in to comment.