LINUX.ORG.RU

Awesome: убирать меню при клике мимо него или переключении на другое окно

 


1

1

Всем привет!

Пробую awesome wm . Немного раздражает непривычное поведение системного меню.

Как сделать, чтобы меню убиралось при клике мимо него или переключении на другое окно?

Спасибо.

★★★★★

В мастере есть хелперная функция, которая это делает:

local function client_menu_toggle_fn()
    local instance = nil
    return function ()
        if instance and instance.wibox.visible then
            instance:hide()
            instance = nil
        else
            instance = awful.menu.clients({ theme = { width = 250 } })
        end
    end
end

Она вешается на клик по клиенту. У меня давно уже своя реализация, которая раскинута по конфигу, и мне щаз лень её собирать по кускам и вспоминать, как она работает, так что юзай эту.

Только instance замени на mymenu, или что там у тебя. Или передавай объект аргументом.

r3lgar ★★★★★
()
Ответ на: комментарий от r3lgar

Или я тебя не понял, или ты меня. Ибо эффект ну совсем не тот.

В любом случае спасибо за наводку. Сделал так: добавил mymainmenu:hide() (mymainmenu - системное меню) на левую кнопку на клиент вот так:

clientbuttons = awful.util.table.join(
     awful.button({ }, 1, function (c) mymainmenu:hide(); client.focus = c; c:raise() end),
Минус - работает только по клику на приложение, но не десктоп, таскбар etc. Сейчас буду искать как реализовать остальное.

Kroz ★★★★★
() автор топика
Последнее исправление: Kroz (всего исправлений: 3)
Ответ на: комментарий от Kroz

Для убирания меню по клику на рут-окно или на любой вибокс — это тебе надо что-то типа этого:

mywibox.connect_signal("mouse::click", function()
  mymainmenu:hide()
  --не забывай уничтожать объект меню, чтобы
  --не было казусов, что он у тебя не с
  --первого раза показывается при вызове:
  mymainmenu = nil
end)
r3lgar ★★★★★
()
Ответ на: комментарий от r3lgar

attempt to index global 'box' (a nil value)
Что с этим делать?

mymainmenu = nil

Это уничтожение объекта???
В С это эталон утечек памяти. Я понимаю, что lua - это не C, ноя ожидал увидеть какой-то delete или типа того....

Kroz ★★★★★
() автор топика
Последнее исправление: Kroz (всего исправлений: 1)
Ответ на: комментарий от Kroz

attempt to index global 'box' (a nil value)

Ты пытаешься оперировать несуществующей переменной/объектом/функцией. Ищи, где ты пытаешься воздействовать на несуществующий box, там же строку показывает.

Это уничтожение объекта???

Это Lua, он весь ущербен. Там и объектов-то как таковых нет. Но для конфигов больше и не надо.

Там перед тем, как отрисовать новое меню, проверяется, не существует ли инстанса с таким именем, а если он имеется, то вместо создания будет проведено его уничтожение, чтобы можно было создать другой инстанс с тем же именем.

r3lgar ★★★★★
()
Ответ на: комментарий от LiBer

Чукча не читатель, чукча — писатель. Он именно это и делает, но хочет другого.

Кстати, фокус при активном меню никуда с активного окна не переходит, перехватываются только кнопки.

Ивенты от мыши в меню (как и в любом вибоксе, коим меню тоже является) обрабатываются только в том случае, если курсор находится на этом вибоксе, так что оно и не должно самопрятаться. Пока лучше не придумали, так что если есть желание и возможность, шли PR.

r3lgar ★★★★★
()
Ответ на: комментарий от Kroz

ожидал увидеть какой-то delete или типа того....

Не придумали ещё. Там даже continue в циклах/условиях нет, что уж говорить об остальном?

r3lgar ★★★★★
()
Ответ на: комментарий от r3lgar

да, я по диагонали прочитал, думал он только на кнопки повесил, подсказал добавить на фокус. Но лично мне мышиная возня эта не интересна.

LiBer ★★★
()
Ответ на: комментарий от LiBer

подсказал добавить на фокус.

Я в первом же комментарии это сделал, лол. Хотя, сабж уже много раз обсуждался, и был реализован сотней способов, искаропки такой возможности нет, и каждый ваяет реализацию так, как ему нравится (благо, на Lua всё равно не будет лучшей реализации из-за его (языка) ущербности).

Но лично мне мышиная возня эта не интересна.

Это нам с тобой оно не нужно, дело привычки. Не надо забывать, что компом могут пользоваться люди, которые буквы на клаве по минуте ищут, а заклинания на клавиатуре, тем более в таких количествах, просто не запомнят. Даже у меня настроен минимальный мышевариант управления, на тот случай, если кто-то попросится посидеть в браузере (которым тоже проще с клавы управлять, лол).

r3lgar ★★★★★
()
Ответ на: комментарий от r3lgar

Пардон, снова попутал сигналы. Тебе нужен press.

Тоже нет такого сигнала.
Я так понял, что press - только для key, button и widget, а для wibox - нет (https://awesome.naquadah.org/wiki/Signals). То есть получается, что нужно определять для каждого виджета.

Осталось понять что такое виджет. Так как вот это не работает:

mytextclock = awful.widget.textclock( " %d.%m.%y %H:%M ", 1)

mytextclock:connect_signal("press", function()
	mymainmenu:hide()
	mymainmenu = nil
end)

Или уж на крайняк где эту инфу найти в исходниках. Сейчас копаю - пока не могу найти...

Kroz ★★★★★
() автор топика
Последнее исправление: Kroz (всего исправлений: 1)
Ответ на: комментарий от r3lgar

Так.
1. Оказывается у wibox есть недокументированный сигнал button:press
2. Делать mymainmenu = nil не нужно, иначе повторный вызов меню приведет к «attempt to index global 'mymainmenu' (a nil value)»

В общем, с wibox заработало так:

mywibox[s]:connect_signal("button::press", function()
  mymainmenu:hide()
  -- mymainmenu = nil
end)

Kroz ★★★★★
() автор топика
Последнее исправление: Kroz (всего исправлений: 1)
Ответ на: комментарий от Kroz

Спасибо. Я себе еще добавил:

 -- {{{ Mouse bindings
 root.buttons(awful.util.table.join(
+    awful.button({ }, 1, function () mymainmenu:hide() end),
     awful.button({ }, 3, function () mymainmenu:toggle() end),
     awful.button({ }, 4, awful.tag.viewnext),
     awful.button({ }, 5, awful.tag.viewprev)
 ))
 -- }}}
Чтобы по клику левой кнопкой мыши на пустом рабочем столе меню тоже пряталось.

feofan ★★★★★
()
Ответ на: комментарий от feofan

Чтобы по клику левой кнопкой мыши на пустом рабочем столе меню тоже пряталось.

Да, только у тебя будет работать только по клику левой кнопки, не средней; не скроллу; и только если ты не зажмешь Ctrl, Alt или любой другой модификатор. Повторное нажатие правой кнопкой закроет это главное меню, хотя естественное поведение - открыть в новом месте. Ну, и напоследок, это работает только для главного меню, а еще есть меню на таскбаре. Весело?

Вот решение без недостатков перечисленных выше:

...
+ hide_mainmenu = true; -- Needed because mainmenu is never destroyed because it is used in mylauncher
+ local function hide_all_menus()
+   -- Main (system) menu
+   if mymainmenu and hide_mainmenu then
+     mymainmenu:hide();
+   end
+   hide_mainmenu = true;
+
+   -- Right-click menu on taskbar
+   if instance then
+     instance:hide()
+     instance = nil
+    end
+ end

...

    mywibox[s]:set_widget(layout)

+   mywibox[s]:connect_signal("button::press", hide_all_menus)
  end
  -- }}}

  -- {{{ Mouse bindings
  root.buttons(awful.util.table.join(
      awful.button({ "Any" }, 0, hide_all_menus),
-     awful.button({ }, 3, function () mymainmenu:toggle() end),
+     -- awful.button({ }, 3, function () mymainmenu:toggle() end),
+     awful.button({ }, 3, function () mymainmenu:toggle(); mymainmenu:show(); hide_mainmenu=false end), -- support for hide menu was added; toggle is needed to hide submenu
      awful.button({ }, 4, awful.tag.viewnext),
      awful.button({ }, 5, awful.tag.viewprev)
  ))

...

  client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
  client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)

+ client.connect_signal("focus", hide_all_menus)
+ client.connect_signal("button::press", hide_all_menus)
  -- }}}

Kroz ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.