IT

Mac - Cmd + Q 를 2회 클릭하여 앱 종료하기

Dante2k™ 2025. 10. 17. 09:04
반응형

맥에서 앱을 종료하지 않고 창만 닫는 키는 Cmd + W 이고, 앱을 완전히 종료하는 키는 Cmd + Q 입니다.

W, Q 키는 바로 옆에 붙어 있어 종종 창만 닫으려고 했는데 앱이 종료되는 경우가 있습니다.

 

하여, Cmd + Q 를 2회 연속 클릭하여 실수로 앱이 종료되는 문제를 해결하는 방법에 대해서 알아보겠습니다.

 

맥의 기본 설정으로는 해결이 불가능하고, Hammerspoon 이라는 앱을 이용해서 간단히 해결하였습니다.

brew 등으로 hammerspoon 을 설치합니다.

brew install --cask hammerspoon

 

Hammerspoon 은 앱 구동 시 ~/.hammerspoon/init.lua 라는 파일의 설정을 로딩하여 동작합니다.

해당 파일에 lua 스크립트로 Cmd + Q 를 2회 연속 클릭하여 앱을 종료하는 기능를 추가합니다.

아래는 해당 스크립트입니다.

-- -------------------------------------------------
--  설정
-- -------------------------------------------------
local quitDelay = 1          -- 확인 타이머 (초)

-- -------------------------------------------------
--  헬퍼 함수
-- -------------------------------------------------
--- 지정한 앱이 종료 가능한지 판단한다.
--- Finder 와 Hammerspoon 은 절대 종료하지 않는다.
--- @param app hs.application|nil  확인할 앱 객체
--- @return boolean  종료 가능하면 true, 아니면 false
local function canKillApp(app)
    if not app then return false end

    local name = app:name()
    if name == "Finder" or name == "Hammerspoon" then
        print("[quit] Cannot kill app: " .. name)
        return false
    end

    -- 여기서 추가적인 예외 처리를 넣을 수 있다.
    -- 예: if name == "System Preferences" then return false end

    print("[quit] Can kill app: " .. name)
    return true
end

-- -------------------------------------------------
--  모달 정의
-- -------------------------------------------------
local quitModal = hs.hotkey.modal.new()   -- 기본(modifiers = none)

-- 모달이 시작될 때 호출
function quitModal:entered()
    hs.alert.show("Press Q again to quit")
    -- 1초 뒤 자동 종료 (타이머를 객체에 저장해 나중에 취소 가능)
    self.timer = hs.timer.doAfter(quitDelay, function()
        self:exit()
    end)
end

-- 모달이 끝날 때 호출 (타이머 정리)
function quitModal:exited()
    if self.timer then
        self.timer:stop()
        self.timer = nil
    end
end

-- 두 번째 키: ⌘+Q 를 눌렀을 때 실제 종료
quitModal:bind({"cmd"}, "q", function()
    local app = hs.application.frontmostApplication()
    if canKillApp(app) then
        app:kill()
    end
    quitModal:exit()   -- 타이머도 위에서 정리됨
end)

-- ESC 로 취소 가능(선택 사항)
quitModal:bind({}, "escape", function()
    quitModal:exit()
end)

-- -------------------------------------------------
--  전역 ⌘+Q 바인딩 : Finder와 Hammerspoon 은 제외하고 모달 진입
-- -------------------------------------------------
hs.hotkey.bind({"cmd"}, "q", function()
    local app = hs.application.frontmostApplication()
    if not app then return end

    if canKillApp(app) then
        print("[quit] Enter quit modal for app: " .. app:name())
        quitModal:enter()
    else
        -- canKillApp 내부에서 이미 로그를 찍었으니 여기서는 아무 것도 안 해도 된다.
    end
end)

 

Finder 는 맥에서 종료되지 않는 앱입니다. 하여 Finder 에 포커스가 있는 경우에는 해당 앱은 종료하지 않게 설정되어 있습니다.

 

끝.

반응형