Điểm:2

Làm cách nào để theo dõi các sự kiện của ứng dụng như mở, đóng, thu nhỏ trong Ubuntu?

lá cờ cc

Tôi muốn biết liệu có thể giám sát các sự kiện mở/đóng/thu nhỏ ứng dụng trong Ubuntu hay không. Mục tiêu ban đầu của tôi là theo dõi xem tôi mở điện tín bao nhiêu lần để kiểm tra tin nhắn.

Tái bút: Tôi đang sử dụng Ubuntu 20.04LTS (X11).

Jacob Vlijm avatar
lá cờ by
Nó phụ thuộc, bạn có đang ở trên X (Không phải wayland) không?
Sasha R Adler avatar
lá cờ cc
@JacobVlijm Có, X11, không phải wayland.
Jacob Vlijm avatar
lá cờ by
Rất tốt có thể. Cần một kịch bản và một số lời giải thích. Tôi sẽ viết một ví dụ nhỏ nếu không có ai nhanh hơn tôi :), nhưng không chắc đó có phải là ngày hôm nay không.
Điểm:3
lá cờ by

Chỉ để cho vui, vì bạn đang ở trên X

Sử dụng python (hoặc nhiều ngôn ngữ khác) Chúng ta có thể sử dụng tín hiệu từ Wnck.ScreenWnck.Window để theo dõi quá trình tạo và/hoặc thay đổi trạng thái của các cửa sổ. Điều này bao gồm tối đa hóa và thu nhỏ cửa sổ.

Đó chính xác là những gì kịch bản dưới đây làm. Sau đó, nó duy trì một tệp nhật ký, tệp này sẽ được cập nhật nếu bạn tạo, thu nhỏ hoặc hủy thu nhỏ cửa sổ của một WM_CLASS cụ thể (và ứng dụng tương tự). Bạn có thể tìm thấy WMCLASS của ứng dụng được nhắm mục tiêu bằng cách mở một thiết bị đầu cuối, gõ xprop WM_CLASS + Trở lại, sau đó nhấp vào chủ đề cửa sổ ("telegramdesktop" cho điện tín hoặc đại loại như thế).

Xin lưu ý rằng tôi đã tạo tập lệnh đặt lại tệp nhật ký sau mỗi phiên (ghi nhật ký), nếu không, tệp nhật ký sẽ trở nên lớn theo thời gian.

Có gì trong tệp nhật ký?

Tệp nhật ký (~/.windowlog.txt) sẽ lưu hồ sơ về việc tạo, đóng và thay đổi trạng thái của (các) cửa sổ của WM_Class đã cho. Mỗi khi cửa sổ không được thu nhỏ, bộ đếm sẽ thêm một cửa sổ, vì vậy, vào cuối ngày, bạn có thể xem hoạt động:

cửa sổ tìm thấy: Telegram
trạng thái đã thay đổi: trực quan (1)
trạng thái đã thay đổi: thu nhỏ
trạng thái đã thay đổi: trực quan (2)
trạng thái đã thay đổi: thu nhỏ
trạng thái đã thay đổi: trực quan (3)
cửa sổ đóng:Telegram
cửa sổ mới:Telegram
trạng thái đã thay đổi: trực quan (4)
trạng thái đã thay đổi: thu nhỏ
trạng thái đã thay đổi: trực quan (5)

Ghi chú rằng tập lệnh được viết với một cửa sổ duy nhất dành cho ứng dụng, giống như tập lệnh trong câu hỏi của bạn. Để giữ một bản ghi chi tiết hơn mỗi cửa sổ, xử lý dữ liệu sẽ yêu cầu mã hóa phức tạp hơn.

Kịch bản

#!/usr/bin/env python3
nhập gi
gi.require_version("Gtk", "3.0")
gi.require_version("Wnck", "3.0")
từ gi.repository nhập Gtk, Wnck
nhập hệ điều hành
nhập khẩu hệ thống


lớp WatchWindow:

    def __init__(bản thân, wmclass):
        self.visual = Không có
        self.count_visual = 0
        self.wnck_scr = Wnck.Screen.get_default()
        self.wmclass = wmclass
        self.logpath = os.environ["HOME"] + "/.windowlog.txt"
        self.run_watching()
        Gtk.main()

    def write_to_log(bản thân, dòng mới):
        với open(self.logpath, "a+") dưới dạng logfile:
            logfile.write(dòng mới + "\n")

    def readable_state(tự, thu nhỏ):
        n = ""
        nếu không giảm thiểu:
            self.count_visual = self.count_visual + 1
            n = "(" + str(self.count_visual) + ")"
        return ["minimized", "visual"][[True, False].index(minimized)] + n
    
    def logstate(bản thân, cửa sổ, *args):
        old_state = self.visual
        new_state = window.is_minimized()
        # chỉ đăng ký nếu trạng thái thu nhỏ thực sự thay đổi
        nếu old_state != new_state:
            self.visual = new_state
            message = "trạng thái đã thay đổi: " + self.readable_state(self.visual) # log
            in (tin nhắn)
            self.write_to_log(tin nhắn)

    def log_new(bản thân, màn hình, cửa sổ):
        nếu window.get_class_group_name().lower() == self.wmclass:
            message = "new window:" + window.get_name() # log new
            in (tin nhắn)
            self.write_to_log(tin nhắn)
            self.watch_window(cửa sổ)
            self.logstate(cửa sổ)

    def log_close(bản thân, màn hình, cửa sổ):
        nếu window.get_class_group_name().lower() == self.wmclass:
            tên = window.get_name()
            self.visual = Không có
            print("cửa sổ đã đóng:", tên) # log đã đóng
    
    def watch_window(self, window, firstcall=False):
        nếu window.get_class_group_name().lower() == self.wmclass:
            nếu cuộc gọi đầu tiên:
                message = "cửa sổ tìm thấy:" + window.get_name()
                in(tin nhắn) # đăng nhập xin vui lòng
                self.write_to_log("cửa sổ tìm thấy: " + window.get_name())
                self.logstate(cửa sổ)
            window.connect("state_changed", self.logstate)

    def run_watching(bản thân):
        cố gắng:
            os.remove(self.logpath)
        ngoại trừ FileNotFoundError:
            vượt qua
        self.wnck_scr.force_update()
        cho w trong self.wnck_scr.get_windows():
            self.watch_window(w, Đúng)
        self.wnck_scr.connect("đã mở cửa sổ", self.log_new)
        self.wnck_scr.connect("cửa sổ đã đóng", self.log_closed)

args = sys.argv[1:]
nếu không tranh luận:
    print("Không đủ tham số! Chúng ta cần một wm_class để xem...")
khác:
    WatchWindow(args[0])

Thiết lập

  1. Sao chép tập lệnh vào một tệp trống, lưu nó dưới dạng windowlogger.pylàm cho nó có thể thực thi được

  2. Kiểm tra- chạy nó trong một cửa sổ đầu cuối, chạy nó với WM_CLASS làm đối số (tôi cho rằng điện tín), Vì thế:

    /path/to/windowlogger telegramdesktop
    
  3. Xem đầu ra trong terminal có ổn không, xem bên trong logfile ~/.windowlog.txt nếu tất cả hoạt động như bình thường.

  4. Thêm nó vào các ứng dụng khởi động của bạn nếu bạn muốn.

NB

Có thể, bạn cần thêm một hoặc nhiều thư viện, kiểm tra đầu ra của thiết bị đầu cuối.

Cửa sổ ghi nhật ký đang hoạt động?

Từ một nhận xét, tôi hiểu rằng bạn coi cửa sổ là "đã sử dụng" (chỉ) nếu đó là cửa sổ đang hoạt động.
Trong trường hợp đó, chúng ta có thể làm cho tập lệnh đơn giản hơn nhiều, vì chúng ta chỉ có cần nhìn vào active_window_changed dấu hiệu. Nếu chúng tôi cũng ghi lại thời gian sử dụng (trên mỗi lần sử dụng / tổng thời gian sử dụng), bạn có thể hiểu rõ bạn đã sử dụng bao nhiêu thời gian khi nhìn vào cửa sổ điện tín (bất kỳ). Tệp nhật ký sau đó trông giống như:

start_time: woensdag, ngày 06 tháng 10 năm 2021, 11:32:53
kích hoạt cửa sổ (1)
cửa sổ ẩn hoặc đóng, đang hoạt động: 0:00:04 tổng: 0:00:04
kích hoạt cửa sổ (2)
cửa sổ ẩn hoặc đóng, đang hoạt động: 0:00:06 tổng: 0:00:10
kích hoạt cửa sổ (3)
cửa sổ ẩn hoặc đóng, đang hoạt động: 0:00:12 tổng: 0:00:22
kích hoạt cửa sổ (4)
cửa sổ ẩn hoặc đóng, đang hoạt động: 0:00:07 tổng: 0:00:29

Kịch bản trong trường hợp đó:

#!/usr/bin/env python3
nhập gi
gi.require_version("Gtk", "3.0")
gi.require_version("Wnck", "3.0")
từ gi.repository nhập Gtk, Wnck
nhập hệ điều hành
nhập khẩu hệ thống
thời gian nhập khẩu
nhập ngày giờ

lớp WatchWindow:

    def __init__(bản thân, wmclass):
        self.visual = Sai
        self.count_visual=1
        self.wnck_scr = Wnck.Screen.get_default()
        self.wmclass = wmclass
        self.logpath = os.environ["HOME"] + "/.windowlog.txt"
        bản thân.total_time = 0
        self.last_time = time.time()
        self.run_watching()
        Gtk.main()

    def write_to_log(bản thân, dòng mới):
        với open(self.logpath, "a+") dưới dạng logfile:
            logfile.write(dòng mới + "\n")

    def get_readable_time(self, đã trôi qua):
        trả về str(datetime.timedelta(giây=đã trôi qua))

    def log_active(self, *args):
        cố gắng:
            # active_class có thể là Không, ví dụ: khi khởi động
            active_class = self.wnck_scr.get_active_window().get_class_group_name()
        ngoại trừ Thuộc tínhError:
            active_class = ""
        newvisual = active_class.lower() == self.wmclass.lower()
        oldvisual = self.visual
        hiện tại = time.time()
        nếu hình ảnh mới != hình ảnh cũ:
            nếu hình ảnh mới:
                self.last_time = hiện tại
                message = "cửa sổ đã kích hoạt (" + str(self.count_visual) + ")"
                self.count_visual = self.count_visual + 1
            khác:
                winactive_time = hiện tại - self.last_time
                self.last_time = hiện tại
                self.total_time = self.total_time + winactive_time
                message = "cửa sổ ẩn hoặc đóng, đang hoạt động: " + \
                          self.get_readable_time(round(winactive_time)) +\
                          "\t" + "tổng: " +\
                          self.get_readable_time(round(self.total_time))
            self.write_to_log(tin nhắn)
        self.visual = newvisual

    def run_watching(bản thân):
        cố gắng:
            os.remove(self.logpath)
        ngoại trừ FileNotFoundError:
            vượt qua
        time_stamp_message = "start_time: " + time.strftime(" %A, %B %d %Y, %H:%M:%S")
        self.write_to_log(time_stamp_message)
        self.wnck_scr.force_update()
        self.wnck_scr.connect("active-window-changed", self.log_active)
        self.log_active()

args = sys.argv[1:]
nếu không tranh luận:
    print("Không đủ tham số! Chúng ta cần một wm_class để xem...")
khác:
    WatchWindow(args[0])

Thiết lập là như nhau.

vanadium avatar
lá cờ cn
Bây giờ chúng tôi cũng cần điều này trên Wayland, vì vậy chúng tôi có thể chuyển đổi;)
Jacob Vlijm avatar
lá cờ by
@vanadium Hehe, đúng rồi.
Sasha R Adler avatar
lá cờ cc
Cảm ơn bạn, đây là những gì tôi muốn. Ngoài ra, tôi đã thêm tín hiệu `đã thay đổi cửa sổ đang hoạt động` để theo dõi xem cửa sổ đang hoạt động có chuyển về điện tín hay không.
Sasha R Adler avatar
lá cờ cc
@JacobVlijm Chắc chắn rồi, điều đó sẽ rất tuyệt.
Jacob Vlijm avatar
lá cờ by
@SashaRAdler đã xong.
Sasha R Adler avatar
lá cờ cc
@JacobVlijm Thật tuyệt, cảm ơn bạn.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.