From 93f67534c63906aa3f79f5a9a4be8d9e9a1059f6 Mon Sep 17 00:00:00 2001 From: GigabiteStudios Date: Fri, 19 Jun 2026 00:35:41 -0500 Subject: [PATCH] fix(ui): reset diff viewer scroll on open --- src/managers/git_manager.cpp | 46 ++++++++++++++++++++++++------------ src/managers/git_manager.h | 3 +++ src/ui/diff_viewer.cpp | 20 ++++++++++++---- src/ui/diff_viewer.h | 1 + 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/managers/git_manager.cpp b/src/managers/git_manager.cpp index a9a0c04..b601a73 100644 --- a/src/managers/git_manager.cpp +++ b/src/managers/git_manager.cpp @@ -80,6 +80,25 @@ namespace return action; } + void populateRepositoryIdentity(RepositoryView &repository) + { + const char *workdir = git_repository_workdir(repository.repo); + repository.path = workdir ? workdir : git_repository_path(repository.repo); + std::filesystem::path path(repository.path); + repository.name = path.filename().string(); + if (repository.name.empty()) + repository.name = path.parent_path().filename().string(); + + repository.branch = "detached"; + git_reference *head = nullptr; + if (git_repository_head(&head, repository.repo) == 0) + { + if (const char *name = git_reference_shorthand(head)) + repository.branch = name; + git_reference_free(head); + } + } + void addBadge(RepositoryView &repository, const git_oid *oid, RefBadge badge) { if (!oid) @@ -539,26 +558,15 @@ bool GitManager::loadRepositoryData(RepositoryView &repository, std::string &err repository.commits.clear(); repository.selected_commit = 0; repository.scroll_to_commit = -1; + repository.undo_action = {}; + repository.redo_action = {}; if (repository.commit_walk) git_revwalk_free(repository.commit_walk); repository.commit_walk = nullptr; repository.history_exhausted = false; loadWorkingTree(repository); - const char *workdir = git_repository_workdir(repository.repo); - repository.path = workdir ? workdir : git_repository_path(repository.repo); - std::filesystem::path path(repository.path); - repository.name = path.filename().string(); - if (repository.name.empty()) - repository.name = path.parent_path().filename().string(); + populateRepositoryIdentity(repository); loadToolbarHistoryActions(repository); - - git_reference *head = nullptr; - if (git_repository_head(&head, repository.repo) == 0) - { - if (const char *name = git_reference_shorthand(head)) - repository.branch = name; - git_reference_free(head); - } readBranches(repository, GIT_BRANCH_LOCAL, repository.local_branches); readBranches(repository, GIT_BRANCH_REMOTE, repository.remote_branches); loadBranchDivergence(repository); @@ -683,7 +691,7 @@ bool GitManager::loadMoreCommits(RepositoryView &repository, size_t page_size, s return true; } -bool GitManager::openRepository(RepositoryView &repository, const std::string &path, std::string &error) +bool GitManager::openRepositoryHandle(RepositoryView &repository, const std::string &path, std::string &error) { git_repository *opened = nullptr; if (git_repository_open_ext(&opened, path.c_str(), 0, nullptr) != 0) @@ -693,6 +701,14 @@ bool GitManager::openRepository(RepositoryView &repository, const std::string &p } repository.close(); repository.repo = opened; + populateRepositoryIdentity(repository); + return true; +} + +bool GitManager::openRepository(RepositoryView &repository, const std::string &path, std::string &error) +{ + if (!openRepositoryHandle(repository, path, error)) + return false; return loadRepositoryData(repository, error); } diff --git a/src/managers/git_manager.h b/src/managers/git_manager.h index 8bb4fcf..d93c351 100644 --- a/src/managers/git_manager.h +++ b/src/managers/git_manager.h @@ -10,6 +10,7 @@ public: GitManager(); ~GitManager(); + bool openRepositoryHandle(RepositoryView &repository, const std::string &path, std::string &error); bool openRepository(RepositoryView &repository, const std::string &path, std::string &error); bool initializeRepository(RepositoryView &repository, const std::string &path, const std::string &initial_branch, std::string &error); @@ -18,6 +19,8 @@ public: bool reload(RepositoryView &repository, std::string &error); bool loadMoreCommits(RepositoryView &repository, size_t page_size, std::string &error); bool checkoutBranch(RepositoryView &repository, const std::string &branch, std::string &error); + bool mergeBranch(RepositoryView &repository, const std::string &source_branch, + const std::string &target_branch, std::string &error); bool fetch(RepositoryView &repository, const std::string &remote, std::string &error); bool pull(RepositoryView &repository, int mode, std::string &error); bool push(RepositoryView &repository, std::string &error); diff --git a/src/ui/diff_viewer.cpp b/src/ui/diff_viewer.cpp index bb6236a..930a772 100644 --- a/src/ui/diff_viewer.cpp +++ b/src/ui/diff_viewer.cpp @@ -657,6 +657,7 @@ void DiffViewer::open(RepositoryView& repository, GitManager& manager, const std commit_id_.clear(); staged_ = staged; mode_ = Mode::diff; + scroll_to_top_ = true; reload(repository, manager, notice); } @@ -666,10 +667,12 @@ void DiffViewer::openCommit(RepositoryView& repository, GitManager& manager, commit_id_ = commit_id; staged_ = false; mode_ = Mode::diff; + scroll_to_top_ = true; reload(repository, manager, notice); if (hunks_.empty()) { mode_ = Mode::file; loadSupplement(repository, manager, mode_, notice); + scroll_to_top_ = true; } } @@ -896,17 +899,24 @@ void DiffViewer::draw(RepositoryView& repository, GitManager& manager, AvatarCac ImGui::SetCursorPosX(std::max(0.0f, (ImGui::GetWindowWidth() - toolbar_width) * 0.5f)); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, {0.0f, ImGui::GetStyle().ItemSpacing.y}); if (toolbarSegmentButton("File View", mode_ == Mode::file, segment_width)) { - mode_ = Mode::file; loadSupplement(repository, manager, mode_, notice); + mode_ = Mode::file; + loadSupplement(repository, manager, mode_, notice); + scroll_to_top_ = true; } ImGui::SameLine(); - if (toolbarSegmentButton("Diff View", mode_ == Mode::diff, segment_width)) mode_ = Mode::diff; + if (toolbarSegmentButton("Diff View", mode_ == Mode::diff, segment_width)) { + mode_ = Mode::diff; + scroll_to_top_ = true; + } ImGui::SameLine(0, between_groups); if (toolbarSegmentButton("Blame", mode_ == Mode::blame, segment_width)) { - mode_ = Mode::blame; loadSupplement(repository, manager, mode_, notice); + mode_ = Mode::blame; + loadSupplement(repository, manager, mode_, notice); } ImGui::SameLine(); if (toolbarSegmentButton("History", mode_ == Mode::history, segment_width)) { - mode_ = Mode::history; loadSupplement(repository, manager, mode_, notice); + mode_ = Mode::history; + loadSupplement(repository, manager, mode_, notice); } ImGui::PopStyleVar(); ImGui::SameLine(0, wrap_gap); @@ -955,7 +965,9 @@ void DiffViewer::draw(RepositoryView& repository, GitManager& manager, AvatarCac } ImGuiWindowFlags content_flags = line_wrap_ ? ImGuiWindowFlags_None : ImGuiWindowFlags_HorizontalScrollbar; + if (scroll_to_top_) ImGui::SetNextWindowScroll({0.0f, 0.0f}); ImGui::BeginChild("diff_content_main", ImVec2{-1, -1}, ImGuiChildFlags_None, content_flags); + scroll_to_top_ = false; const bool use_code_font = code_font && mode_ != Mode::history; if (use_code_font) ImGui::PushFont(code_font, 0.0f); const float row_height = scaled(21, scale); diff --git a/src/ui/diff_viewer.h b/src/ui/diff_viewer.h index 9a379e0..16b86a9 100644 --- a/src/ui/diff_viewer.h +++ b/src/ui/diff_viewer.h @@ -61,6 +61,7 @@ private: std::vector blame_lines_; std::vector history_entries_; bool line_wrap_ = false; + bool scroll_to_top_ = false; void reload(RepositoryView& repository, GitManager& manager, std::string& notice); void loadSupplement(RepositoryView& repository, GitManager& manager, Mode mode, std::string& notice);