fix(ui): reset diff viewer scroll on open

This commit is contained in:
2026-06-19 00:35:41 -05:00
parent 5ba7d46809
commit 93f67534c6
4 changed files with 51 additions and 19 deletions

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -61,6 +61,7 @@ private:
std::vector<BlameLine> blame_lines_;
std::vector<HistoryEntry> 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);