diff --git a/src/components/TopMenuSection.vue b/src/components/TopMenuSection.vue
index b43d96edc..12954fd90 100644
--- a/src/components/TopMenuSection.vue
+++ b/src/components/TopMenuSection.vue
@@ -17,6 +17,7 @@
class="[&:not(:has(*>*:not(:empty)))]:hidden"
>
@@ -38,7 +39,13 @@
-
+
+
+
@@ -57,6 +64,7 @@ import CurrentUserButton from '@/components/topbar/CurrentUserButton.vue'
import LoginButton from '@/components/topbar/LoginButton.vue'
import { useCurrentUser } from '@/composables/auth/useCurrentUser'
import { buildTooltipConfig } from '@/composables/useTooltipConfig'
+import { useSettingStore } from '@/platform/settings/settingStore'
import { app } from '@/scripts/app'
import { useRightSidePanelStore } from '@/stores/workspace/rightSidePanelStore'
import { useWorkspaceStore } from '@/stores/workspaceStore'
@@ -64,11 +72,20 @@ import { isElectron } from '@/utils/envUtil'
const workspaceStore = useWorkspaceStore()
const rightSidePanelStore = useRightSidePanelStore()
+const settingsStore = useSettingStore()
const { isLoggedIn } = useCurrentUser()
const isDesktop = isElectron()
const { t } = useI18n()
const isQueueOverlayExpanded = ref(false)
const actionbarContainerRef = ref()
+const isActionbarDocked = ref(true)
+const actionbarPosition = computed(() => settingsStore.get('Comfy.UseNewMenu'))
+const isActionbarEnabled = computed(
+ () => actionbarPosition.value !== 'Disabled'
+)
+const isActionbarFloating = computed(
+ () => isActionbarEnabled.value && !isActionbarDocked.value
+)
// Right side panel toggle
const { isOpen: isRightSidePanelOpen } = storeToRefs(rightSidePanelStore)
diff --git a/src/components/actionbar/ComfyActionbar.vue b/src/components/actionbar/ComfyActionbar.vue
index 3d565b8b2..aa0e6a965 100644
--- a/src/components/actionbar/ComfyActionbar.vue
+++ b/src/components/actionbar/ComfyActionbar.vue
@@ -1,7 +1,7 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
- {{ queuedCount }}
-
- {{ queuedSuffix }}
-
-
-
-
-
+
+
+
+
+
+
+ {{ queuedCount }}
+
+ {{ queuedSuffix }}
+
+
+
+
+
+
+
+
+
+
+
-
+
()
const emit = defineEmits<{
(e: 'update:queueOverlayExpanded', value: boolean): void
+ (e: 'update:docked', value: boolean): void
}>()
const settingsStore = useSettingStore()
@@ -124,18 +142,31 @@ const position = computed(() => settingsStore.get('Comfy.UseNewMenu'))
const visible = computed(() => position.value !== 'Disabled')
const tabContainer = document.querySelector('.workflow-tabs-container')
+const actionbarWrapperRef = ref(null)
const panelRef = ref(null)
const dragHandleRef = ref(null)
-const isDocked = useLocalStorage('Comfy.MenuPosition.Docked', true)
+const storedDocked = useLocalStorage('Comfy.MenuPosition.Docked', true)
+const docked = computed({
+ get: () => props.docked ?? storedDocked.value,
+ set: (value) => {
+ storedDocked.value = value
+ emit('update:docked', value)
+ }
+})
const storedPosition = useLocalStorage('Comfy.MenuPosition.Floating', {
x: 0,
y: 0
})
+watchEffect(() => emit('update:docked', docked.value))
+const wrapperElement = computed(() => {
+ const element = unrefElement(actionbarWrapperRef)
+ return element instanceof HTMLElement ? element : null
+})
const panelElement = computed(() => {
const element = unrefElement(panelRef)
return element instanceof HTMLElement ? element : null
})
-const { x, y, style, isDragging } = useDraggable(panelElement, {
+const { x, y, style, isDragging } = useDraggable(wrapperElement, {
initialValue: { x: 0, y: 0 },
handle: dragHandleRef,
containerElement: document.body,
@@ -186,12 +217,12 @@ watchDebounced(
// Set initial position to bottom center
const setInitialPosition = () => {
- const panelEl = panelElement.value
- if (panelEl) {
+ const containerEl = wrapperElement.value
+ if (containerEl) {
const screenWidth = window.innerWidth
const screenHeight = window.innerHeight
- const menuWidth = panelEl.offsetWidth
- const menuHeight = panelEl.offsetHeight
+ const menuWidth = containerEl.offsetWidth
+ const menuHeight = containerEl.offsetHeight
if (menuWidth === 0 || menuHeight === 0) {
return
@@ -260,12 +291,12 @@ watch(
)
const adjustMenuPosition = () => {
- const panelEl = panelElement.value
- if (panelEl) {
+ const containerEl = wrapperElement.value
+ if (containerEl) {
const screenWidth = window.innerWidth
const screenHeight = window.innerHeight
- const menuWidth = panelEl.offsetWidth
- const menuHeight = panelEl.offsetHeight
+ const menuWidth = containerEl.offsetWidth
+ const menuHeight = containerEl.offsetHeight
// Calculate distances to all edges
const distanceLeft = lastDragState.value.x
@@ -336,21 +367,22 @@ const onMouseLeaveDropZone = () => {
watch(isDragging, (dragging) => {
if (dragging) {
// Starting to drag - undock if docked
- if (isDocked.value) {
- isDocked.value = false
+ if (docked.value) {
+ docked.value = false
}
} else {
// Stopped dragging - dock if mouse is over drop zone
if (isMouseOverDropZone.value) {
- isDocked.value = true
+ docked.value = true
}
// Reset drop zone state
isMouseOverDropZone.value = false
}
})
+const isFloating = computed(() => visible.value && !docked.value)
const inlineProgressTarget = computed(() => {
if (!visible.value) return null
- if (!isDocked.value) return panelElement.value
+ if (isFloating.value) return panelElement.value
return props.topMenuContainer ?? null
})
const actionbarClass = computed(() =>
@@ -365,11 +397,21 @@ const actionbarClass = computed(() =>
)
const panelClass = computed(() =>
cn(
- 'actionbar z-1300 relative overflow-hidden rounded-[var(--p-panel-border-radius)]',
- isDocked.value
- ? 'p-0 static mr-2 border-none bg-transparent'
- : 'fixed shadow-interface',
+ 'actionbar z-1300 overflow-hidden rounded-[var(--p-panel-border-radius)]',
+ docked.value ? 'p-0 static mr-2 border-none bg-transparent' : 'fixed',
isDragging.value ? 'select-none pointer-events-none' : 'pointer-events-auto'
)
)
+const panelRootClass = computed(() =>
+ cn(
+ 'relative overflow-hidden rounded-[var(--p-panel-border-radius)]',
+ docked.value
+ ? 'border-none shadow-none bg-transparent'
+ : 'border border-interface-stroke shadow-interface'
+ )
+)
+
+defineExpose({
+ isFloating
+})