xkorfun / winlego

winlego manual

winlego lives in the menu bar as a grid icon. Filled means it is on and allowed; hollow means it is off or still waiting for permission.

Permission

winlego needs Accessibility access to see and move other apps' windows. On first launch a window asks for it; the button opens System Settings › Privacy & Security › Accessibility (named Device Control and Data Access on macOS 27). Flip the switch next to winlego. The app notices within a second.

Nothing else is needed: no Input Monitoring, no Screen Recording. winlego does not read keystrokes and has no network code.

Layouts

Every display has a layout: a set of zones. Pick one under Layouts in the menu bar, or in Settings › Layouts, where a small preview shows each layout's shape. Landscape displays start with Wide Left (⅔ + ⅓); portrait displays start with Top + Bottom.

Built-in layouts:

LayoutZones
Full ScreenOne zone: the whole usable screen. For small displays.
HalvesLeft, Right
Wide Left (⅔ + ⅓)Left ⅔, Right ⅓
Wide Right (⅓ + ⅔)Left ⅓, Right ⅔
ThirdsLeft, Center, Right
Grid 2×2Top Left, Top Right, Bottom Left, Bottom Right
Left + Right StackLeft (60%), Top Right, Bottom Right
Center ColumnLeft (15%), Center (70%), Right (15%)
Top + BottomTop, Bottom
Three RowsTop, Middle, Bottom
Tall Top (⅔ + ⅓)Top ⅔, Bottom ⅓

Zones never cover the menu bar or the Dock. Settings › Layouts › Spacing adds a gap between neighbouring zones.

Layouts you draw yourself or adjust on screen appear above the built-in ones as My layouts.

Placing windows

A window is placed when winlego has put it in a zone. Four ways:

Zones shown while dragging with Shift; with Control held, Top Right and Bottom Right are merged

  • Drag with ⇧. Start dragging any window by its title bar, hold ⇧ (you can press it mid-drag), and every display shows its zones. The zone under the cursor lights up; let go to place the window there. Settings › General can change the trigger to ⌥, or to Always so zones appear on every drag.
  • Merge zones: add ⌃. Once the drag is under way and the zones are showing, hold ⌃ as well and move the cursor across neighbouring zones on one display. Press ⌃ only after you have grabbed the window: control-click before that is a right-click and no drag starts. (⌥ is not used: macOS shows its own tiling preview on option-drag.) Each one you touch joins the selection; let go and the window fills them all. The layout itself does not change; only that window spans several zones. Dragging the boundary inside a spanned window does nothing, since the window covers both sides.
  • Shortcuts. By default ⌃⌥← and ⌃⌥→ move the focused window to the previous or next zone on its display, wrapping around. A window that is not placed yet starts from the zone it overlaps most. ⌃⌥↑ and ⌃⌥↓ move it to the same zone number on the previous or next display (left to right, then top to bottom).
  • Menu bar › Move Window to. Lists every display and its zones.
  • Rules. See below.

winlego only places standard windows. Sheets, panels, dialogs, minimized windows and windows in their own full-screen Space are left alone. Apps with a minimum window size get as close to the zone as they can.

Keeping windows in place

Once placed, a window stays placed:

  • If the app moves or resizes its own window (restoring a saved position, say), winlego puts it back a moment later.
  • When a display is connected, disconnected or rearranged, or the Mac wakes up, winlego waits a moment for the system to settle, then puts every placed window back.
  • Changing a display's layout re-places its windows in the new zones. A window whose zone number no longer exists goes to the last zone.

Your own actions win:

  • Drag a placed window somewhere else (without ⇧) and it is released. It is yours again until you place it.
  • ⌃⌥⌫ or Release This Window does the same without moving it.
  • An app that keeps moving its window back, or a window that cannot be made to fit, is released rather than fought over.

Placements are remembered until the window closes or winlego quits. To have windows placed again after a restart, use rules.

Rules

A rule says: windows of this app go to this zone of this display.

The quickest way to make one: place a window where you want it and choose Remember This Window Here in the menu bar. The app's windows now open there, and Arrange All by Rules (⌃⌥↩) moves every window with a rule into place.

Settings › Rules edits them:

  • Title contains limits a rule to windows whose title includes the text. A rule with a title filter wins over the app-wide rule for the same app, so you can send one project's windows elsewhere.
  • Display defaults to the main display. If the chosen display is not connected, the rule uses the main display.
  • Add Rule for App… lists the apps running right now.

Settings › General › Ignored apps lists apps whose windows rules never touch.

Resizing zones on screen

When two placed windows sit in neighbouring zones, the boundary between them can be dragged, like a split in a tiling window manager:

After dragging the boundary, winlego asks whether to save the new proportions

  1. Move the cursor onto the boundary. A coloured bar with a grip appears on it. It appears only where the boundary is visible: if another window lies on top of it, there is no bar.
  2. Drag. Both windows (and any others in the affected zones) follow live.
  3. Let go. A small prompt asks Save this layout for <display>?
    • Save keeps the new proportions as that display's layout. If the display was using a built-in layout, a copy named like Wide Left (⅔ + ⅓) · LG HDR 4K is created under My layouts; from then on that copy is edited in place.
    • Not Now (or letting the countdown run out; Settings › General sets how long, or turns the automatic dismissal off) leaves the windows as they are but keeps the saved layout unchanged. New placements on that display use the dragged proportions until you pick a layout again or restart.

A boundary is only draggable while there are placed windows on both sides of it.

The layout editor

Settings › Layouts › New Layout… opens the editor on a single full-screen zone; Edit… next to one of My layouts opens that layout.

  • Click a zone to select it.
  • Split Left | Right and Split Top / Bottom divide the selected zone in two equal parts. Keep splitting to build grids, stacks, sidebars.
  • Drag the handle on any boundary to change the split.
  • Remove Zone gives its space to the neighbour it was split from.
  • Name the selected zone in the field on the right; unnamed zones are called Zone 1, Zone 2… in reading order.
  • The Landscape / Portrait switch only changes the preview's shape.
  • Save stores the layout under the name at the top. It is then available for every display.

Deleting a layout from My layouts reverts any display using it to the default.

Settings

Menu bar › Settings… (⌘,).

  • Rules: see above.
  • Layouts: my layouts, layout per display, spacing.
  • General: drag trigger, shortcuts, ignored apps, Open at Login, permission status.

Changing shortcuts

Settings › General › Shortcuts lists every action with its keys. Click the keys, press the new combination, done. Esc cancels. The arrow button restores the default; the cross removes the shortcut. Function keys may be used alone; any other key needs ⌃, ⌥ or ⌘ so ordinary typing is never swallowed. A warning triangle means another app already holds that combination.

Language

winlego follows the system language: Korean when macOS is set to Korean, English otherwise. Layout and zone names are translated too; names you type yourself stay as typed.

Everything is stored in ~/Library/Application Support/winlego/config.json. Delete the file to start over.

Troubleshooting

Nothing happens. Check the icon: hollow means winlego is off (toggle Keep Windows in Zones) or not permitted. After an update, macOS sometimes drops the permission; remove winlego from the Accessibility list and add it again.

macOS's own tiling gets in the way. macOS 15 and later offer to tile a window when you drag it to a screen edge, and that can trigger before you reach a zone. Turn it off under System Settings › Desktop & Dock › Drag windows to screen edges to tile.

The resize cursor does not appear on a boundary. Known limitation: macOS does not let a background app change the cursor. The highlighted bar marks the boundary; dragging works regardless.

A window ends up the wrong size. Some apps enforce a minimum size or a fixed aspect ratio; winlego aligns them to the zone's top-left corner. Chromium and Electron apps occasionally resize wrongly while their accessibility "enhanced user interface" mode is on; winlego turns it off during a move.

A window keeps jumping back and forth. winlego gives up after a few rounds and releases the window. Add the app to Ignored apps if it is a habit.

Shortcuts do nothing. Another app may own the combination. winlego registers through the system hot key service, which refuses a combination that is taken, and marks the row with a warning in Settings › General. Pick another one there.

Logs. winlego writes to the unified log:

/usr/bin/log show --last 5m --info --predicate 'subsystem == "io.github.esteban-eg-kim.winlego"'

(Use the full path: zsh has a built-in log command that silently does nothing.)

winlego 매뉴얼

winlego 는 메뉴바에 격자 아이콘으로 있습니다. 채워진 아이콘은 켜져 있고 권한도 있는 상태, 비어 있으면 꺼져 있거나 아직 권한을 기다리는 상태입니다.

권한

winlego 는 다른 앱의 창을 보고 옮기기 위해 손쉬운 사용 권한이 필요합니다. 첫 실행 때 안내 창이 뜨고, 버튼을 누르면 시스템 설정 › 개인정보 보호 및 보안 › 손쉬운 사용(macOS 27 에서는 기기 제어 및 데이터 접근)이 열립니다. winlego 옆 스위치를 켜면 1초 안에 인식합니다.

다른 권한은 필요 없습니다. 입력 모니터링도, 화면 기록도 아닙니다. 키 입력을 읽지 않고 네트워크 코드도 없습니다.

레이아웃

디스플레이마다 레이아웃(영역 묶음)이 하나씩 있습니다. 메뉴바 Layouts 또는 설정 › Layouts 에서 고릅니다. 설정 쪽에는 모양 미리보기가 있습니다. 가로 디스플레이는 Wide Left (⅔ + ⅓), 세로 디스플레이는 Top + Bottom 으로 시작합니다.

기본 레이아웃:

레이아웃영역
Full Screen영역 하나, 화면 전체. 작은 디스플레이용.
Halves왼쪽, 오른쪽
Wide Left (⅔ + ⅓)왼쪽 ⅔, 오른쪽 ⅓
Wide Right (⅓ + ⅔)왼쪽 ⅓, 오른쪽 ⅔
Thirds왼쪽, 가운데, 오른쪽
Grid 2×2좌상, 우상, 좌하, 우하
Left + Right Stack왼쪽(60%), 우상, 우하
Center Column왼쪽(15%), 가운데(70%), 오른쪽(15%)
Top + Bottom위, 아래
Three Rows위, 가운데, 아래
Tall Top (⅔ + ⅓)위 ⅔, 아래 ⅓

영역은 메뉴바와 Dock 을 침범하지 않습니다. 설정 › Layouts › Spacing 으로 영역 사이에 간격을 둘 수 있습니다.

직접 그리거나 화면에서 조절한 레이아웃은 My layouts 로 기본 레이아웃 위에 나옵니다.

창 넣기

winlego 가 창을 영역에 넣으면 그 창은 배정된 상태입니다. 방법은 네 가지:

⇧ 를 누른 채 끌 때 보이는 영역. ⌃ 까지 눌러 우상과 우하를 합친 모습

  • ⇧ 드래그. 창의 제목 표시줄을 끌면서 ⇧ 를 누르면(드래그 도중에 눌러도 됨) 모든 디스플레이에 영역이 표시됩니다. 커서 아래 영역이 강조되고, 놓으면 거기에 들어갑니다. 설정 › 일반에서 트리거를 ⌥ 로 바꾸거나 항상(모든 드래그에 표시)으로 바꿀 수 있습니다.
  • 영역 합치기: ⌃ 추가. 끌기가 시작되어 영역이 보이는 동안 ⌃ 까지 누르고 한 디스플레이 안에서 이웃한 영역들로 커서를 옮기면 지나간 영역이 차례로 선택에 더해집니다. ⌃ 는 창을 잡은 뒤에 누르세요. 먼저 누른 채 클릭하면 우클릭이 되어 드래그가 시작되지 않습니다. (⌥ 는 macOS 가 자체 타일링 안내를 띄워서 쓰지 않습니다.) 놓으면 창이 그 영역들을 모두 채웁니다. 레이아웃은 바뀌지 않고 그 창만 여러 영역에 걸칩니다. 걸친 창 안쪽의 경계는 양쪽을 같은 창이 덮고 있어 끌어도 아무 일이 없습니다.
  • 단축키. 기본값으로 ⌃⌥← / ⌃⌥→ 는 현재 창을 같은 디스플레이의 이전/다음 영역으로 옮깁니다(끝에서 순환). 아직 배정되지 않은 창은 가장 많이 겹치는 영역에서 출발합니다. ⌃⌥↑ / ⌃⌥↓ 는 이전/다음 디스플레이(왼쪽→오른쪽, 위→아래 순)의 같은 번호 영역으로 옮깁니다.
  • 메뉴바 › Move Window to. 디스플레이와 영역 목록.
  • 규칙. 아래 참고.

winlego 는 일반 창만 다룹니다. 시트, 패널, 대화상자, 최소화된 창, 자체 전체 화면 Space 에 있는 창은 건드리지 않습니다. 최소 크기가 있는 앱은 영역에 최대한 가깝게 맞춥니다.

자리 유지

한 번 배정된 창은 계속 배정 상태입니다.

  • 앱이 스스로 창을 옮기거나 크기를 바꾸면(저장된 위치 복원 등) 잠시 뒤 되돌립니다.
  • 디스플레이를 연결·분리·재배치하거나 Mac 이 절전에서 깨어나면, 시스템이 안정될 때까지 잠깐 기다렸다가 배정된 창을 전부 제자리로 돌립니다.
  • 디스플레이의 레이아웃을 바꾸면 창들이 새 영역에 다시 배치됩니다. 영역 번호가 더 이상 없는 창은 마지막 영역으로 갑니다.

사용자의 행동이 우선입니다.

  • 배정된 창을 ⇧ 없이 직접 끌어 다른 곳에 놓으면 배정이 풀립니다. 다시 배정할 때까지 자유로운 창입니다.
  • ⌃⌥⌫ 또는 Release This Window 는 옮기지 않고 풀기만 합니다.
  • 창을 계속 되돌려 놓는 앱, 영역에 맞출 수 없는 창은 싸우는 대신 풀어 줍니다.

배정은 창이 닫히거나 winlego 가 종료될 때까지 기억합니다. 재시작 뒤에도 자동으로 배치되게 하려면 규칙을 쓰세요.

규칙

규칙은 이 앱의 창은 이 디스플레이의 이 영역으로 입니다.

가장 빠른 방법: 창을 원하는 곳에 넣고 메뉴바에서 Remember This Window Here. 이제 그 앱의 창은 거기서 열리고, Arrange All by Rules(⌃⌥↩)는 규칙 있는 창을 전부 제자리로 보냅니다.

설정 › Rules 에서 편집합니다.

  • Title contains 는 제목에 그 글자가 든 창으로 규칙을 한정합니다. 제목 필터가 있는 규칙이 같은 앱의 앱 전체 규칙보다 우선하므로, 특정 프로젝트 창만 다른 곳으로 보낼 수 있습니다.
  • Display 기본값은 메인 디스플레이입니다. 고른 디스플레이가 연결돼 있지 않으면 메인 디스플레이를 씁니다.
  • Add Rule for App… 은 지금 실행 중인 앱을 보여 줍니다.

설정 › General › Ignored apps 의 앱은 규칙이 건드리지 않습니다.

화면에서 영역 크기 조절

배정된 창 두 개가 이웃한 영역에 있으면, 그 사이 경계를 타일링 창 관리자의 분할선처럼 끌 수 있습니다.

경계를 끈 뒤 새 비율을 저장할지 묻는 팝업

  1. 커서를 경계에 올립니다. 경계 위에 색 막대와 손잡이가 나타납니다. 경계가 보일 때만 나타납니다. 다른 창이 경계 위를 덮고 있으면 나오지 않습니다.
  2. 끕니다. 양쪽 창(그리고 영향 받는 영역의 다른 창)이 실시간으로 따라옵니다.
  3. 놓습니다. 작은 창이 이 레이아웃을 <디스플레이> 에 저장할까요? 라고 묻습니다.
    • Save 는 새 비율을 그 디스플레이의 레이아웃으로 저장합니다. 기본 레이아웃을 쓰고 있었다면 Wide Left (⅔ + ⅓) · LG HDR 4K 같은 이름의 사본이 My layouts 에 생기고, 이후엔 그 사본이 제자리에서 수정됩니다.
    • 나중에(또는 카운트다운이 끝나도록 두기. 시간은 설정 › 일반에서 바꾸거나 자동 닫힘을 끌 수 있음)는 창은 그대로 두고 저장된 레이아웃은 바꾸지 않습니다. 그 디스플레이의 새 배치는 레이아웃을 다시 고르거나 재시작할 때까지 끌어 놓은 비율을 씁니다.

경계는 양쪽에 배정된 창이 있을 때만 잡힙니다.

레이아웃 에디터

설정 › Layouts › New Layout… 은 전체 화면 영역 하나로 에디터를 엽니다. My layouts 옆의 Edit… 은 그 레이아웃을 엽니다.

  • 영역을 클릭해 선택합니다.
  • Split Left | Right, Split Top / Bottom 은 선택한 영역을 반으로 가릅니다. 계속 갈라서 격자, 쌓기, 사이드바를 만듭니다.
  • 경계의 손잡이를 끌어 비율을 바꿉니다.
  • Remove Zone 은 그 공간을 갈라져 나온 이웃에게 돌려줍니다.
  • 오른쪽 입력란에서 선택한 영역의 이름을 정합니다. 이름 없는 영역은 읽는 순서대로 Zone 1, Zone 2… 입니다.
  • Landscape / Portrait 는 미리보기 모양만 바꿉니다.
  • Save 는 위의 이름으로 저장합니다. 모든 디스플레이에서 고를 수 있습니다.

My layouts 에서 레이아웃을 지우면 그걸 쓰던 디스플레이는 기본값으로 돌아갑니다.

설정

메뉴바 › Settings…(⌘,).

  • Rules: 위 참고.
  • Layouts: 내 레이아웃, 디스플레이별 레이아웃, 간격.
  • 일반: 드래그 트리거, 단축키, 무시할 앱, 로그인 시 열기, 권한 상태.

단축키 바꾸기

설정 › 일반 › 단축키에 모든 동작과 키가 있습니다. 키를 클릭하고 새 조합을 누르면 끝입니다. Esc 는 취소. 화살표 버튼은 기본값 복원, X 는 단축키 없애기. 기능키는 단독으로 쓸 수 있고, 다른 키는 평소 타이핑을 삼키지 않도록 ⌃, ⌥, ⌘ 중 하나가 필요합니다. 경고 삼각형은 다른 앱이 그 조합을 이미 쓰고 있다는 뜻입니다.

언어

winlego 는 시스템 언어를 따릅니다. macOS 가 한국어면 한국어, 아니면 영어입니다. 레이아웃과 영역 이름도 번역되며, 직접 입력한 이름은 그대로 둡니다.

모든 설정은 ~/Library/Application Support/winlego/config.json 에 있습니다. 처음부터 다시 하려면 이 파일을 지우세요.

문제 해결

아무 일도 안 일어남. 아이콘을 보세요. 비어 있으면 꺼져 있거나(Keep Windows in Zones 토글) 권한이 없는 것입니다. 업데이트 뒤 macOS 가 권한을 떨어뜨리기도 합니다. 손쉬운 사용 목록에서 winlego 를 지우고 다시 추가하세요.

macOS 자체 타일링이 끼어듦. macOS 15 부터 창을 화면 가장자리로 끌면 타일링을 제안하는데, 영역에 닿기 전에 먼저 걸릴 수 있습니다. 시스템 설정 › 데스크탑 및 Dock › 화면 가장자리로 드래그하여 타일링 을 끄세요.

경계에서 리사이즈 커서가 안 보임. 알려진 제한입니다. macOS 는 백그라운드 앱이 커서를 바꾸는 것을 허용하지 않습니다. 강조 막대가 경계를 표시하고, 드래그는 그대로 됩니다.

창 크기가 이상함. 최소 크기나 고정 비율을 강제하는 앱이 있습니다. winlego 는 그런 창을 영역의 왼쪽 위에 맞춥니다. Chromium·Electron 앱은 손쉬운 사용의 "향상된 사용자 인터페이스" 모드가 켜져 있으면 가끔 크기가 틀어지는데, winlego 는 옮기는 동안 그 모드를 끕니다.

창이 계속 왔다 갔다 함. winlego 는 몇 번 시도하면 포기하고 창을 풀어 줍니다. 자주 그러는 앱은 Ignored apps 에 넣으세요.

단축키가 안 됨. 다른 앱이 그 조합을 쓰고 있을 수 있습니다. winlego 는 시스템 핫키 서비스에 등록하는데 이미 쓰는 조합은 거부되고, 설정 › 일반에서 그 줄에 경고가 표시됩니다. 거기서 다른 조합을 고르세요.

로그. winlego 는 통합 로그에 씁니다.

/usr/bin/log show --last 5m --info --predicate 'subsystem == "io.github.esteban-eg-kim.winlego"'

(전체 경로로 쓰세요. zsh 에는 내장 log 명령이 있어서 조용히 아무것도 안 합니다.)